std::is_default_constructible<T> 错误(如果构造函数是私有的)
std::is_default_constructible<T> error, if constructor is private
我有以下代码段
#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编译,没有任何错误
相关文章:
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 如果有一个模板构造函数只有一个泛型参数,为什么我必须有一个复制构造函数
- 如果基类包含双指针成员,则派生类的构造函数
- 如果我真的真的想从 STL 容器继承,并且我继承构造函数并删除新运算符,会发生什么?
- 基类中的默认析构函数禁用子类中的移动构造函数(如果有成员)
- 如果存在从"双精度"到"T"的转换,则禁用构造函数
- 在 C++ 中声明 const 对象需要用户定义的默认构造函数.如果我有一个可变成员变量,为什么不呢?
- 如果这不是类的"复制构造函数",是否可以移动对象?
- 在 c++ 中,如果我创建一个接受一个具有默认值的参数的构造函数 - 它会用作默认(空)构造函数吗?
- 如果我也使用复制构造函数并且重载 = 运算符,我是否需要析构函数?
- 如果在 C++ 构造函数中以错误的顺序初始化对象数据,会发生什么类型的错误
- 如果普通默认构造函数不执行任何操作,为什么我们不能使用 malloc 创建平凡可构造的对象?
- 如果我想从类型"T"定义元素的容器(来自 STL),那么"T"必须使用默认构造函数?
- 为 unordered_map 中的元素设置默认构造函数(如果是 [] 运算符)
- 我打算调用initializer_list构造函数,如果存在,则事先调用复制构造函数:为什么?
- 如果在C++中不需要构造函数或析构函数,是否有必要显式声明它?
- 如果构造函数和析构函数可以获取和显示(打印)数据,为什么我们需要 getter 和 setter?
- 如果函数按值传递并按值返回,将调用复制构造函数多少次
- 如果我们有 (N)RVO,当实际调用移动构造函数时?
- 调用类型的标记构造函数(如果可用),否则为默认值