2016-03-10 49 views
3

我试图让默认构造函数= default;有条件取决于类模板参数的属性使用以下方法:明确违约模板化的构造

#include <type_traits> 
#include <utility> 
#include <iostream> 

#include <cstdlib> 

template< typename T > 
struct identity 
{ 

}; 

template< typename T > 
struct has_property 
    : std::false_type 
{ 

}; 

template< typename T > 
struct S 
{ 
    template< typename X = T, 
       typename = std::enable_if_t< !has_property<X>::value > > 
    S(identity<X> = {}) 
    { std::cout << __PRETTY_FUNCTION__ << std::endl; } 

    template< typename X = T, 
       typename = std::enable_if_t< has_property<X>::value > > 
#if 0 
    S() = default; 
#else 
    S() 
    { std::cout << __PRETTY_FUNCTION__ << std::endl; } 
#endif 
}; 

struct A {}; 
struct B {}; 

template<> 
struct has_property<B> 
    : std::true_type 
{ 

}; 

int main() 
{ 
    S<A>{}; 
    S<B>{}; 
    return EXIT_SUCCESS; 
} 

#if 1它给出了一个错误:

main.cpp:32:11: error: only special member functions may be defaulted 
    S() = default; 
     ^

template<...> S()不是的默认构造函数的声明S

我可以在将来使用概念来实现这样的调度吗?

回答

2

我认为这是由[dcl.fct.def.default]涵盖:

A function that is explicitly defaulted shall:

  • be a special member function,
  • have the same declared function type (except for possibly differing ref-qualifiers and except that in the case of a copy constructor or copy assignment operator, the parameter type may be “reference to non-const T”, where T is the name of the member function’s class) as if it had been implicitly declared,

在你的情况下,隐式声明的默认构造函数不会是一个函数模板,所以你不能明确违约它。

GCC 5.x给出您的错误代码,error: a template cannot be defaulted

+0

@Orient OK。我对这个答案并不是100%肯定的,如果标准明确表示“模板不能默认”,虽然我找不到这样的文本,但本来不错。我不完全确定“声明的函数类型”对于函数模板意味着什么。 –

+0

@Orient你打算编辑你的帖子来删除'constexpr'吗? –

+0

@Orient好吧,直到我发表评论后才显示出来 –