c++ - std::is_default_constructible<T> 错误,如果构造函数是私有(private)的

标签 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");
}

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

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

好的。由于这个条件真的不平等 - 我们可以使用这样的东西

#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 不应该失败,因为类型实际上不是默认可构造的/不可抛出构造的。 问题是:为什么会出现编译错误,而不是我的静态断言?​​

最佳答案

看起来像是一个编译器错误。让我们看看下面的 SFINAE 示例(g++type_traits header 中使用了类似的实现)

#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 类型,因为该类只有一个 deleted 构造函数。但是,当编译器尝试推断 Private() 的类型时,它会给出错误:Private::Private() is private。因此,我们有两个具有私有(private)构造函数的类,但其中一个会出错,而第二个不会。我认为,这种行为是错误的,但我无法在标准中找到确认。

附言所有显示的代码都由 clang 编译,没有任何错误。

关于c++ - std::is_default_constructible<T> 错误,如果构造函数是私有(private)的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14030070/

相关文章:

C++:在模板化类型中存在命名成员时在模板化类中提供类函数?

C++检测类型是否为字符串对象

c++ - Qt Gridlayout 不重新对齐 GUI 元素

c++ - 有没有办法在编译时和运行时之间专门化一个函数?

c++ - 在 C++ 程序运行期间输入输入值 (./filename.out)

c++ - 使用以下 has_member 函数时 SFINAE 无法正常工作的原因是什么?

c++ - 获取 c 数组上 begin 的返回类型

C++11 嵌套 std::conditional

c++ - 跨平台、开源、控制台 GUI

c++ - std::set_intersection,带偏移量的交集列表