显式默认模板构造函数

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 的默认构造函数声明吗?

我能否在未来使用即将到来的概念来实现这样的分派?

1个回答

2
我认为这个问题在[dcl.fct.def.default]中有所涉及:
一个显式默认的函数应该满足以下条件: - 是一个特殊成员函数 - 与其隐式声明的函数类型相同(除了可能不同的ref-qualifiers和参数类型,如果是复制构造函数或复制赋值运算符,则参数类型可以是“非const T的引用”,其中T是成员函数类的名称)
在你的情况下,隐式声明的默认构造函数将不会是一个函数模板,因此你不能显式默认它。
对于你的代码,GCC 5.x会给出错误提示:error: a template cannot be defaulted

@Orient 好的。我对这个答案并不完全确定,如果标准明确说明“模板不能被默认”,那就更好了,尽管我找不到这样的文字。对于函数模板,“声明的函数类型”是什么意思,我也不完全确定。 - M.M
@Orient 你打算编辑你的帖子删除 constexpr 吗? - M.M
@Orient 好的,直到我发表了那条评论后一段时间它才出现。 - M.M

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接