2016-03-10 96 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好吧,直到我發表評論後才顯示出來 –