临时绑定到引用是否需要C++中的复制构造函数
Does binding temporary to a reference require a copy constructor in C++?
考虑以下代码:
class A {
A(const A&);
public:
A() {}
};
int main() {
const A &a = A();
}
此代码在GCC 4.7.2中编译良好,但在Visual C++2010中编译失败,出现以下错误:
test.cc(8) : error C2248: 'A::A' : cannot access private member declared in class 'A'
test.cc(2) : see declaration of 'A::A'
test.cc(1) : see declaration of 'A'
那么,在将临时绑定到引用时,是否需要有一个可访问的复制构造函数?
这在一定程度上与我之前的问题有关:
有没有办法禁止将临时绑定到常量引用?
那么,在将临时绑定到引用时,是否需要有一个可访问的复制构造函数
C++11之后-否
C++11之前-是。
此代码与GCC 4.7.2一起编译良好,因为它符合C++11标准。
C++11标准规定,当从prvalue
初始化常量引用时,它必须直接绑定到引用对象,并且不允许创建临时引用。此外,复制构造函数未被使用或是必需的。
在C++11之前,规则有所不同。这种行为(是否调用复制构造函数)是实现定义的。C++03允许在将常量引用绑定到临时时调用复制构造函数,因此在C++11之后,复制构造函数需要是可访问的。Visual C++2010遵循C++03标准。
C++03标准的第8.5.3.5节指出,这是实现定义的:
如果初始值设定项表达式是右值,其中T2是类类型,并且;cv1T1";是参考兼容的";cv2T2;引用以以下方式之一绑定(选择由实现定义):
--引用绑定到由右值表示的对象(见3.10)或该对象中的子对象。
--类型为";cv1T2";创建[sic],并调用构造函数将整个右值对象复制到临时对象中。引用绑定到临时对象或临时对象中的子对象。
将用于制作副本的构造函数应是可调用的,无论副本是否实际完成。
因此,这两种实现似乎都与C++03标准一致。
最后一句话有点令人困惑,但从我的阅读方式来看,这意味着实现可能会选择第二种方式,但仍然会优化掉副本。在这种情况下,即使复制实际上没有完成,复制构造函数也必须是可访问的,类似于返回值优化。
对于C++11标准,第二种方式不再是一种选择。
Visual C++不正确;标准没有指示复制构造函数必须是可访问的以将CCD_ 2引用绑定到临时的。
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 在C++程序中输入的文本文件将不起作用,除非文本被复制和粘贴
- 使用strcpy将char数组的元素复制到另一个数组
- 是否可以初始化不可复制类型的成员变量(或基类)
- 为什么在C++中使用私有复制构造函数与删除复制构造函数
- C++ Windows 驱动程序MSB3030无法复制该文件,因为它找不到
- 复制列表初始化的隐式转换的等级是多少
- 当从函数参数中的临时值调用复制构造函数时
- 有可能在Armadillo中复制MATLAB circshift方法吗
- 复制几乎为空的数组的最快方法
- 以下示例中如何避免代码复制?C++/库达
- 如果有一个模板构造函数只有一个泛型参数,为什么我必须有一个复制构造函数
- 为什么需要复制构造函数,在哪些情况下它们非常有用
- 不能将复制初始化与隐式转换的多个步骤一起使用
- 当有分配器意识的容器被复制/移动时,反弹分配器是否被复制/移走
- 为什么复制而不是移动数据元素?
- 文件系统:复制功能的速度秘诀是什么
- 使用仅使用一次的变量调用的复制构造函数.这可能是通过调用move构造函数进行编译器优化的情况吗
- 为什么类中的ostringstream类型的成员会导致";调用隐含删除复制构造函数";错误
- 使lambda不可复制/不可移动