变长模板在typedef中的参数展开

3

给定以下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容器。我该如何展开它们,同时保留它们之间的&&检查?


你应该尝试一下 Hypodermic 的新版本。 - mister why
2个回答

4
在C++17中,您可以这样做:
using IsSignatureRecognized = BoolType<(ArgResolver<Args>::IsResolvable::value && ...)>;

在此之前,您需要自行创建一个可变参数 'and'。


这真的很好,但我正在使用c++11编译。这是我尝试的第一件事(除了使用语句而不是typedef),但显然它没有编译成功。 - Stefano

3

只需像这样编写一个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_,它接受任意数量的类型。第一个特化检查包中的第一个参数,如果为假,则无需继续,因为整个and_将为假。如果为真,则继续检查其余的参数。一旦没有剩余参数,没有参数的特化就会简单地返回true。
这是一个例子:
and_<t, t, f, t>::value
gives conditional<t::value, and_<t, f, t>, f>::type

因为条件为真,type 评估为第二个参数 and_<t,f,t>。类似地,对于下一个参数,我们得到:

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

现在条件为假,因此type评估为第三个参数f,我们完成模板实例化,::value给出false
如果所有参数都为真,则最终会到达and_<>,我们将其专门设置为std::true_type,以便::value给出true
希望这有助于澄清此代码的工作原理。

它能工作!你能解释一下这段代码吗?我是个新手,还在学习可变参数模板,所以我并没有真正理解你做了什么。 - Stefano
请注意,类似的东西已经被添加到C++17中,名为std::conjunction - Simple
谢谢你的解释,我非常感激。@Simple 非常酷,你知道 Visual Studio 2015 是否支持它吗? - Stefano

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接