【问题标题】:Explicitly defaulting a templated constructor显式默认模板化构造函数
【发布时间】:2016-06-24 20:23:23
【问题描述】:

我尝试使用以下技术根据类模板参数的属性有条件地制作 默认构造函数 = 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&lt; ... &gt; S() 不是 S默认构造函数 的声明吗?

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

【问题讨论】:

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


    【解决方案1】:

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

    明确默认的函数应:

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

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

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

    【讨论】:

    • @Orient OK。我不是 100% 确定这个答案,如果标准确实明确地说“模板不能被默认”,那会很好,尽管我找不到这样的文本。我不完全确定“声明的函数类型”对函数模板意味着什么。
    • @Orient 你要编辑你的帖子以删除constexpr 吗?
    • @Orient 好的,直到我发表评论后一段时间才出现
    猜你喜欢
    • 2014-05-18
    • 2011-03-27
    • 1970-01-01
    • 1970-01-01
    • 2016-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多