在 C++0x 中,非静态数据成员初始值设定项是否会覆盖隐式复制构造函数?
根据 N2628 相关 c++0x 中,非静态数据成员初始值设定项可以被显式定义的构造函数覆盖,但对于隐式定义的复制构造函数似乎有点模糊。
特别是,我注意到,在 Apple clang 3.0 版中,行为会根据结构(或类)是否是 POD 而有所不同。
以下程序返回输出“1”,这表明复制构造函数忽略右侧,而是替换为新的非静态数据成员初始值设定项(在此示例中,X::a 的布尔 true 值) )。
#include <iostream>
#include <string>
struct X
{
std::string string1;
bool a = true;
};
int main(int argc, char *argv[])
{
X x;
x.a = false;
X y(x);
std::cout << y.a << std::endl;
}
然而,令人困惑的是,如果您注释掉 string1:
// std::string string1;
那么行为将按我的预期工作(输出为“0”),大概是因为没有隐式生成的复制构造函数,因此数据被复制 。
C++0x 规范是否真的表明允许隐式定义的复制构造函数不复制右侧的内容是一个好主意?这不是不太有用而且不直观吗?我发现非静态成员初始值设定项功能非常方便,但如果这是正确的行为,那么我将明确避免该功能,因为它的行为很棘手且不直观。
请告诉我我错了?
更新:此错误已在 Clang 源存储库中修复。请参阅此修订版。
更新:此错误似乎已在 Apple clang 版本 3.1 (tags/Apple/clang-318.0.45) 中修复(基于 LLVM 3.1svn)。此版本的 clang 作为 Lion 的 Xcode 4.3 的一部分进行分发。
According to N2628 related to c++0x, non-static data member initializers can be overridden by explicitly defined constructors, but it appears to be slightly nebulous about the implicitly defined copy constructor.
In particular, I've noticed that with Apple clang version 3.0, the behavior varies depending on whether the struct (or class) is a POD.
The following program returns output "1", which indicates that the copy-constructor is ignoring the right-hand-side, and instead substituting the new non-static data member initializer (in this example, the boolean true value for X::a).
#include <iostream>
#include <string>
struct X
{
std::string string1;
bool a = true;
};
int main(int argc, char *argv[])
{
X x;
x.a = false;
X y(x);
std::cout << y.a << std::endl;
}
However, confusingly, if you comment out string1:
// std::string string1;
then the behavior works as I expected (the output is "0"), presumably because there is no implicitly generated copy-constructor, and therefore the data is copied.
Does the C++0x specification really suggest that it is a good idea to allow the implicitly defined copy-constructor to not copy the contents of the right-hand side? Isn't that less useful and unintuitive? I find the non-static member initializer functionality to be quite convenient, but if this is the correct behavior, then I will explicitly avoid the feature due to its tricky and unintuitive behavior.
Please tell me I'm wrong?
UPDATE: This bug has been fixed in the Clang source repository. See this revision.
UPDATE: This bug appears fixed in Apple clang version 3.1 (tags/Apple/clang-318.0.45) (based on LLVM 3.1svn). This version of clang was distributed as part of Xcode 4.3 for Lion.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
它毕竟不是阴影,请参阅标准摘录的突出显示部分:
关于默认复制/移动构造函数的部分(第 12.8 节)有点太长,无法完整引用。底层是带有初始值设定项的非静态成员字段仍然简单地由默认的复制/移动构造函数
第 12.8 节复制:
这是引用的示例:
为了完整起见,默认的默认构造函数的相应部分:
§ 12.1
It isn't shadowy after all, see highlighted parts of the standards excerpt:
The section on defaulted copy/move constructors (§ 12.8) is a bit too lengthy to quote in it's entirety. The low-down is that non-static member fields with initializers are still simply copied by the defaulted copy/move constructor
§ 12.8:
This is the sample referred to:
For completeness, the corresponding section on the defaulted default constructor:
§ 12.1