【问题标题】:Detect if a default constructor exists at compile time [duplicate]检测编译时是否存在默认构造函数[重复]
【发布时间】:2012-12-09 10:04:52
【问题描述】:

我正在尝试检查模板参数是否存在默认构造函数。 我想做这样的事情:

template <typename A>
class Blah
{
   Blah() { A* = new A(); } 
}

但我想在编译时通过 SFINAE 或其他技巧检测该构造函数是否存在,如果不存在,则提出我自己的 static_assert

当我的类(如std::vector)没有“默认构造函数”但具有默认参数的构造函数时,就会出现问题。

所以使用std::has_trivial_default_constructor 不会返回true。虽然我可以使用new vector&lt;T&gt;()

【问题讨论】:

  • std::is_default_constructible 还不行吗?
  • 在 VS2010 中不存在......此外,如果有默认构造函数,它被定义为返回 true。例如哪个向量没有,但可以不带参数构造。
  • 拥有所有默认参数仍使其成为默认构造函数。 GCC 4.7.2 说 std::vector is default-constructible.

标签: c++ templates constructor sfinae


【解决方案1】:

这是类型特征的可能实现:

template<typename T>
class is_default_constructible {

    typedef char yes;
    typedef struct { char arr[2]; } no;

    template<typename U>
    static decltype(U(), yes()) test(int);

    template<typename>
    static no test(...);

public:

    static const bool value = sizeof(test<T>(0)) == sizeof(yes);
};

struct foo {
    foo(int) {}
};

int main()
{
    std::cout << is_default_constructible<foo>::value << '\n'        // 0
              << is_default_constructible<std::vector<int>>::value;  // 1
}

【讨论】:

  • 太棒了,decltype() 究竟是如何工作才能在这里获得 SFINAE 的?
  • 两个操作数上的逗号运算符.. 对。
  • 没错,它被称为 expression sfinae - 右操作数为我们提供了我们想要的类型,如果表达式无效,则左操作数用于替换失败。
【解决方案2】:

C++ 标准中没有std::has_trivial_default_constructor;这似乎是来自 Boost 的 gcc 增强。这不是你想要的。您不想检查某些东西是否具有微不足道的默认构造函数;您想检查某个类是否具有默认构造函数,无论是否微不足道。使用std::is_default_constructible(假设是兼容 c++11 的编译器)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多