C++ 为什么具有非常量复制构造函数的类不被视为可复制构造函数?
给定C++ 为什么具有非常量复制构造函数的类不被视为可复制构造函数?,c++,copy-constructor,C++,Copy Constructor,给定 std::is\u copy\u constructible::valueisfalse Foo具有有效的副本构造函数:来自草案n4659: struct Foo { Foo(Foo&) {} }; 但是是可构造的测试是可构造的(常量) 为什么具有非常量复制构造函数的类不被视为可复制构造函数?虽然这确实是一个有效的复制构造函数,但定义了是可复制的类型特征以给出与是可构造的相同的结果,因为它旨在对应于标准中定义的CopyConstructible概念 里面说 C++标
std::is\u copy\u constructible::value
isfalse
Foo具有有效的副本构造函数:来自草案n4659:
struct Foo
{
Foo(Foo&) {}
};
但是是可构造的
测试是可构造的
(常量)
为什么具有非常量复制构造函数的类不被视为可复制构造函数?虽然这确实是一个有效的复制构造函数,但定义了
是可复制的
类型特征以给出与是可构造的
相同的结果,因为它旨在对应于标准中定义的CopyConstructible
概念
里面说
C++标准库中的模板定义引用了各种命名要求,其详细内容列于表20至27中。在这些表中,<代码> T <代码>是由C++程序提供模板的一种对象或引用类型;[…]和v是类型为(可能为const)T的左值或类型为const T的右值
可复制的概念定义如下: 表24:可复制的要求(除可移动的要求外)表达后条件
tu=v;v的值不变,等于u
T(v)v的值不变,等于T(v)
因此,由于对象不能从
const Foo
左值构造,这是CopyConstructible
的要求之一,因此它不被认为是这样的。from,它相当于std::is_constructible::value
,您仍然可以使用std::is_constructible::value
@Jarod42实际上,我不能。它在库调用中内部使用,如emplace\u back
tostd::vector
…@relaxx它在内部用于提供良好的错误消息,即使它不在那里,您的代码也不可能编译:由于您声明了复制构造函数,移动操作不再隐式生成<但是,有时需要增加向量,从而尝试将元素移动到新缓冲区中。因此,使用std::move
(或类似内容)将旧元素转换为xvalue,但是,当尝试在新缓冲区中构造元素时,它们无法绑定到副本构造函数中的Foo&
。您需要添加一个接受Foo&&
的移动构造函数,或者添加一个接受Foo const&
的额外副本构造函数,或者将现有副本构造函数更改为接受fooconst&
(无论是否添加移动构造函数,您都应该这样做)。请注意,拥有一个实际修改另一个Foo
的复制构造函数可能会导致令人惊讶的行为,因为编译器允许在某些条件下删除副本(并且在C++17中保证这样做)@Corristo不错的评论。std::is\u copy\u constructible
如std::is\u copy\u constructible\u with\u good\u constructor
。
15.8.1 Copy/move constructors [class.copy.ctor]
1
A non-template constructor for class X is a copy constructor if its first parameter is of type X& , const X& ,
volatile X& or const volatile X& , and either there are no other parameters or else all other parameters
have default arguments (11.3.6). [Example: X::X(const X&) and X::X(X&,int=1) are copy constructors.