为什么我没有从volatile提供一个默认的复制构造函数? [英] Why am I not provided with a default copy constructor from a volatile?
问题描述
此代码:
class X {
int member;
};
volatile X a;
X b = a;
由于错误而失败:
prog.cpp:6:7:错误:没有匹配函数调用'X :: X(volatile X&)'
prog.cpp:6:7: are:
prog.cpp:1:7:note:X :: X()
prog.cpp:1:7:note:candidate expects 0 arguments,1 provided
prog.cpp :1:7:note:X :: X(const X&)
prog.cpp:1:7:注意:参数1从'volatile X'到'const X&'$有没有什么办法我可以让编译器为我生成一个volatile副本构造函数? $ b 解决方案简单的答案是:因为标准说你不会。
标准12.8 / 9(草案N3242)告诉:
类X的隐式声明的拷贝构造函数将具有
- X :: X(const X&)
如果
- X的每个直接或虚拟基类B都有一个复制构造函数,
B&或const volatile B&和
- 对于类型为M(或其数组)的X的所有非静态数据成员,每个这样的类
类型具有第一个参数的类型为const M&或const volatile M&。 [注意:119]
否则,隐式声明的复制构造函数将采用< >
- X :: X(X&)
注意119说:
这意味着参考参数的隐式声明的复制构造函数不能绑定到volatile lvalue ;
在C.1.9中,您会发现:
隐式声明的拷贝构造函数和隐式声明的拷贝赋值运算符不能对volatile lvalue进行
拷贝。例如,以下在ISO C中有效:
struct X {int i; };
volatile struct X x1 = {0};
struct X x2(x1); // invalid C ++
struct X x3;
x3 = x1; //也无效C ++
对若干备选方案进行了详细辩论。将参数更改为volatile const X&将极大地复杂化类对象的高效代码的生成。讨论为这些隐式定义的操作提供两个可替换的签名引起了关于创建歧义和使根据基础和成员指定形成这些操作符的规则复杂化的未解决的问题。
This code:
class X {
int member;
};
volatile X a;
X b = a;
Fails with the error:
prog.cpp:6:7: error: no matching function for call to ‘X::X(volatile X&)’
prog.cpp:6:7: note: candidates are:
prog.cpp:1:7: note: X::X()
prog.cpp:1:7: note: candidate expects 0 arguments, 1 provided
prog.cpp:1:7: note: X::X(const X&)
prog.cpp:1:7: note: no known conversion for argument 1 from ‘volatile X’ to ‘const X&’
Is there any way I can get the compiler to generate a volatile copy constructor for me?
解决方案 The short answer is: Because the standard says you won't.
The C++ Standard 12.8/9 (Draft N3242) tells:
The implicitly-declared copy constructor for a class X will have the form
- X::X(const X&)
if
- each direct or virtual base class B of X has a copy constructor whose first parameter is of type const
B& or const volatile B&, and
- for all the non-static data members of X that are of a class type M (or array thereof), each such class
type has a copy constructor whose first parameter is of type const M& or const volatile M&. [Note: 119]
Otherwise, the implicitly-declared copy constructor will have the form
- X::X(X&)
Note 119 says:
This implies that the reference parameter of the implicitly-declared copy constructor cannot bind to a volatile lvalue;
see C.1.9.
In C.1.9 you'll find:
The implicitly-declared copy constructor and implicitly-declared copy assignment operator cannot make a
copy of a volatile lvalue. For example, the following is valid in ISO C:
struct X { int i; };
volatile struct X x1 = {0};
struct X x2(x1); // invalid C++
struct X x3;
x3 = x1; // also invalid C++
Rationale: Several alternatives were debated at length. Changing the parameter to volatile const X& would greatly complicate the generation of efficient code for class objects. Discussion of providing two alternative signatures for these implicitly-defined operations raised unanswered concerns about creating ambiguities and complicating the rules that specify the formation of these operators according to the bases and members.
这篇关于为什么我没有从volatile提供一个默认的复制构造函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!