std :: enable_if作为构造函数的单个参数

时间:2014-02-24 11:37:21

标签: c++ c++11 template-meta-programming enable-if

我对模板元编程很新,并且已经完成了一些概念 - 但是,我遇到过这个特殊的片段,我感到很难过。

template<class TAG, typename... DATATYPES>
struct Message {

    Message (typename std::enable_if<sizeof...(DATATYPES) >= 1>) {
    }

    ... (various other constructor declarations here)

    std::tuple<DATATYPES...> m_data;
};

我在读它的时候假设它是在启用默认构造函数的情况下,如果有一个或多个DATATYPES参数,但是我测试了所有这些都是编译错误。

我很感激帮助我理解这个片段的任何帮助,因为我理解了enable_if应该做什么,但在这种情况下,我似乎无法理解实际发生的事情。

编辑:我想这不是'如何实现这种特殊效果?'的问题。更多的是“这段代码实际产生的是什么,它是否符合我所理解的原始作者的意图?”

2 个答案:

答案 0 :(得分:4)

如果std::enable_if后面没有,则

::type未正确使用。 std::enable_if<expr>本身是一种相当无用的struct类型。

有条件地启用默认构造函数的正确方法:

template<class TAG, typename... DATATYPES>
struct Message {
private:
    struct dummy_type {};
public:
    template <typename T = std::tuple<DATATYPES...>>
    Message(
        typename std::enable_if<std::tuple_size<T>() >= 1, dummy_type>::type
        = dummy_type{}
    ) {}
    //...
};

Live at coliru.

答案 1 :(得分:1)

成员函数签名是类定义的一部分,需要在实例化类时解析。这意味着编译器也会尝试enable_if,如果条件未满,则会发现它没有嵌套的type - 硬错误。

要使SFINAE正常工作,您需要使构造函数成为模板,并使enable_if依赖于模板参数。例如,请参阅@ acheplers的答案。

OP中的代码是一种断言DATATYPE pack大小的奇怪方式,可以更清楚地使用static_assert。或者,作者可能只是不知道如何正确地进行SFINAE。