std :: is_default_constructible <t>错误,如果构造函数是私有的</t>

时间:2012-12-25 11:07:59

标签: c++ c++11 typetraits

我有以下代码段

#include <type_traits>
#include <boost/type_traits.hpp>

class C { C() { } };

int main()
{
   static_assert(!boost::has_trivial_default_constructor<C>::value, "Constructible");
   static_assert(!std::is_default_constructible<C>::value, "Constructible");
}

条件不相等,但第一个条件工作正常,第二个构造给出错误,构造函数是私有的。编译器gcc 4.7 ...那么,这个gcc错误,还是由标准定义的?

http://liveworkspace.org/code/NDQyMD $ 5'/ P>

行。由于这个条件确实不相等 - 我们可以使用类似的东西

#include <type_traits>
#include <boost/type_traits.hpp>

class C { private: C() noexcept(false) { } };

int main()
{
   static_assert(!boost::has_nothrow_constructor<C>::value, "Constructible");
   static_assert(!std::is_nothrow_constructible<C>::value, "Constructible");
}

http://liveworkspace.org/code/NDQyMD $ 24

无论如何,我知道,static_assert应该不会失败,因为类型实际上不是默认的可构造/不可构造的。 问题是:为什么存在编译错误,而不是我的静态断言?​​

1 个答案:

答案 0 :(得分:5)

看起来像编译器错误。让我们看一下SFINAE的以下示例(类似的实现在g++的{​​{1}}标题中使用)

type_traits

第二个断言按预期工作,我们不能推导出#include <type_traits> class Private { Private() { } }; class Delete { Delete() = delete; }; struct is_default_constructible_impl { template<typename T, typename = decltype(T())> static std::true_type test(int); template<typename> static std::false_type test(...); }; template <class T> struct is_default_constructible: decltype(is_default_constructible_impl::test<T>(0)) { }; int main() { static_assert(is_default_constructible<Private>::value, "Private is not constructible"); static_assert(is_default_constructible<Delete>::value, "Delete is not constructible"); } 类型,因为该类只有一个已删除的构造函数。但是当编译器尝试推导出Delete的类型时,它会给出错误:Private()。所以,我们有两个私有构造函数的类,但其中一个给出了错误,第二个 - 没有。我认为,这种行为是错误的,但我在标准中找不到确认。

P.S。所有关闭的代码都由clang编译而没有任何错误。