我对模板元编程很新,并且已经完成了一些概念 - 但是,我遇到过这个特殊的片段,我感到很难过。
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应该做什么,但在这种情况下,我似乎无法理解实际发生的事情。
编辑:我想这不是'如何实现这种特殊效果?'的问题。更多的是“这段代码实际产生的是什么,它是否符合我所理解的原始作者的意图?”
答案 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{}
) {}
//...
};
答案 1 :(得分:1)
成员函数签名是类定义的一部分,需要在实例化类时解析。这意味着编译器也会尝试enable_if
,如果条件未满,则会发现它没有嵌套的type
- 硬错误。
要使SFINAE正常工作,您需要使构造函数成为模板,并使enable_if
依赖于模板参数。例如,请参阅@ acheplers的答案。
OP中的代码是一种断言DATATYPE
pack大小的奇怪方式,可以更清楚地使用static_assert
。或者,作者可能只是不知道如何正确地进行SFINAE。