typedef中的可变模板拆包参数

Variadic template unpacking arguments in typedef

本文关键字:包参数 参数 typedef      更新时间:2023-10-16

给定以下C++typedef表达式

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;

我在问自己是否可以用一个可变的模板来完成。代码来自Hypodermic IoC容器。如何打开它们的包装,同时在它们之间保留&&检查?

在C++17中,您可以执行以下操作:

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

之前,你必须自己制作一个变异体"and"。

只需编写一个and_元函数,如下所示:

    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{};

我还没有测试过,所以可能会有几个打字错误,但我希望你能明白。

然后你这样使用它:

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

它的工作方式相当简单,我们有一个通用类template <class...> and_,它接受任何数量的类型。第一个专门化检查包中的第一个参数,如果它为false,则无需继续,因为整个and_都将为false。如果这是真的,那么我们继续检查其余的参数。一旦没有更多的参数了,没有参数的专门化就简单地返回true。

这里有一个例子:

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

因为条件为true,所以type计算为第二个参数and_<t, f, t>。类似地,对于下一个参数,我们得到:

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

现在条件为false,所以type计算为第三个参数f,我们完成了模板的实例化,::value给了我们false

如果所有的参数都是真的,那么你最终会到达and_<>,我们专门称之为std::true_type,所以::value给了我们true

我希望这有助于澄清这个代码是如何工作的。