2014-02-24 52 views
1

我对模板元编程相当陌生,并且一直在研究一些概念 - 但是,我遇到了这个特定片段,我一直被困住了。std :: 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; 
}; 

读它时,它被启用默认的构造函数,如果有一个或更多类型的参数,但已经测试过所有我得到的是一个编译错误我承担了。

我希望在帮助我理解这段代码时提供任何帮助,因为我明白enable_if应该做什么,但在这种情况下,我似乎无法将我的头围绕在实际发生的事情上。

编辑:我想这不是一个'我如何达到这个特殊效果?'的问题。并且更多地沿着'这段代码实际产生了什么,这与我所理解的原始作者的意图相匹配吗?'。

+0

我没有时间发布完整的解决方案,但看看http://stackoverflow.com/questions/21901637/class-template-why-cant-i-specializea-a-单一方法为void类型/ 21904225#21904225,相同的技术可以应用于您的问题,除了使用'IsVoid',而不是使用'IsVoid',您将基于arg类型的数量来定义。 –

+1

作为一个经验法则,如果你在一个不是模板的函数中看到'enable_if'(即类模板的成员不计数),那就错了。 –

回答

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.

+0

是的,谢谢@jrok。 – aschepler

+0

不幸的是,它不会工作。构造函数本身需要是一个模板。 – jrok

+0

它正在做什么,如果enable_if条件的计算结果为true,则创建一个带有结构arg的(无用)构造函数? – GMemory

1

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

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

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

+0

感谢您的见解,非常感谢。我有一种直觉,认为代码没有按照它的意图去做,但我对于能够确切地说明的概念缺乏牢固的把握。 – GMemory

+0

不客气。 – jrok

相关问题