明确默认一个模板化的构造函数

时间:2016-03-10 06:10:10

标签: c++ templates c++11 c++14 default-constructor

我尝试使用以下技术有条件地使用默认构造函数 = 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不是吗?

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

1 个答案:

答案 0 :(得分:2)

我认为[dcl.fct.def.default]涵盖了这一点:

  

明确默认的功能应:

     
      
  • 是一个特殊的会员功能,
  •   
  • 具有相同的声明函数类型(可能不同的ref限定符除外,在复制构造函数或复制赋值运算符的情况下,参数类型可以是“引用非const T”,其中T是成员函数的类的名称),就像它已被隐式声明一样,
  •   

在您的情况下,隐式声明的默认构造函数不会是函数模板,因此您无法显式默认它。

GCC 5.x为您的代码error: a template cannot be defaulted提供了错误。