简体   繁体   中英

Variadic template unpacking arguments in typedef

Given the following C++ typedef expression

template <bool> struct BoolType : std::true_type {};

template <> struct BoolType< false > : std::false_type {};

typedef BoolType< ArgResolver< Arg1 >::IsResolvable::value && ArgResolver< Arg2 >::IsResolvable::value > IsSignatureRecognized;

I was asking myself if it could be done with a variadic template. The code comes from Hypodermic IoC container. How can I unpack them while retaining the && check between each of them?

In C++17, you may do:

using IsSignatureRecognized = BoolType<(ArgResolver<Args>::IsResolvable::value && ...)>;

before, you have to make an variadic ' and ' by yourself.

Just write up an and_ metafunction like this:

    template <class ... Bools>
    struct and_;

    template <class Bool, class ... Bools>
    struct and_<Bool, Bools...> : std::conditional<
        Bool::value, and_<Bools...>, std::false_type>::type{};

    template <>
    struct and_<> : std::true_type{};

I haven't tested this so there may be a couple of typos, but I hope you get the idea.

Then you use it like this:

    typedef and_<typename ArgResolver<Args>::IsResolvable...> IsSignatureRecognized;

The way it works is fairly simple, we have the generic class template <class...> and_ which accepts any number of types. The first specialization checks the first argument in the pack, if it's false there's no need to continue since the whole and_ will be false. If it's true then we continue checking the rest of the parameters. Once there are no more parameters left, the specialization with no parameters simply returns true.

Here's an example:

and_<t, t, f, t>::value
gives conditional<t::value, and_<t, f, t>, f>::type

Because the condition is true, type evaluates to the second parameter and_<t, f, t> . Similarly for the next parameter, we get to:

and_<f, t>::value
gives conditional<f::value, and_<t>, f>::type

Now the condition is false so type evaluates to the third parameter f and we are done instantiating templates and ::value gives us false .

If all the parameters are true you will eventually reach and_<> which we specialized to be std::true_type so that ::value gives us true .

I hope that helps clarify how this code works.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM