为什么具有非const复制构造函数的类不被视为可复制构造?

时间:2017-04-25 09:30:48

标签: c++ copy-constructor

给出

struct Foo 
{
    Foo(Foo&) {} 
};

std::is_copy_constructible<Foo>::valuefalse

Foo拥有有效的拷贝构造函数:来自草案n4659:

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.

is_copy_constructible根据标准测试is_constructible_v<T, const T&> const )。

为什么具有非const复制构造函数的类不被视为可复制构造?

1 个答案:

答案 0 :(得分:4)

虽然这确实是一个有效的复制构造函数,但is_copy_constructible类型特征被定义为提供与is_constructible_v<T, const T&>相同的结果,因为它旨在对应于CopyConstructible概念,也是由标准定义的。

[utility.arg.requirements]/1中说

  

C ++标准库中的模板定义是指各种命名要求,其详细信息在表20-27中列出。在这些表中,T是由实例化模板的C ++程序提供的对象或引用类型; [...]和v是类型的左值(可能是const )T或类型为const T的右值。

CopyConstructible概念在Table 24中定义为

  

表24 - CopyConstructible要求(除了MoveConstructible)
  表达后条件
  T u = v; v的值不变,相当于u
  T(v)v的值不变,等于T(v)

因此,由于您的对象无法从const Foo左值开始构造,这是CopyConstructible的要求之一,因此不会将其视为此类。