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

std::is_default_constructible<T> error, if constructor is private

本文关键字:构造函数 如果 default is constructible lt gt std 错误      更新时间:2023-10-16

我有以下代码段

#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 bug,还是标准定义的?

http://liveworkspace.org/code/NDQyMD

5美元

OK。由于这些条件实际上是不等的-我们可以使用像这样的

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

看起来像是编译器错误。让我们看看下面的SFINAE示例(类似的实现在g++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()类型时,给出了错误:Private::Private() is private。因此,我们有两个带有私有构造函数的类,但其中一个给出错误,另一个没有。我认为这种行为是错误的,但是我在标准中找不到证实。

注:所有关闭的代码由clang编译,没有任何错误

相关文章: