1

我对模板元编程相当陌生,并且一直在研究一些概念 - 但是,我遇到的这个特定片段让我有点难过。

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 应该做什么,但在这种情况下,我似乎无法理解实际发生的事情。

编辑:我想这不是“我如何实现这种特殊效果?”的问题。以及更多类似“此代码实际生成的内容,它是否符合我所理解的原作者的意图?”

4

2 回答 2

4

std::enable_if如果后面没有 . 则不能正确使用::typestd::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{}
    ) {}
    //...
};

住在科里鲁。

于 2014-02-24T11:50:03.977 回答
1

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

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

OP 中的代码所做的是一种奇怪的断言DATATYPE包大小的方式,这static_assert将更清楚地完成。或者,也许作者只是不知道如何正确地做 SFINAE。

于 2014-02-24T12:12:16.143 回答