#include <iostream>
struct A{
A(int){
}
~A(){
std::cout<<"A destroy\n";
}
};
struct B{
B(int){
std::cout<<"B construct\n";
}
~B(){
std::cout<<"B destroy\n";
}
};
struct Content{
A const& a;
};
struct Data{
Data():c{0},b{0}{
}
Content c;
B b;
};
int main(){
Data d;
std::cout<<"exit\n";
}
Run Code Online (Sandbox Code Playgroud)
GCC的输出是:
B construct
A destroy
exit
B destroy
Run Code Online (Sandbox Code Playgroud)
Clang 抱怨此代码格式错误。这是两个编译器的性能。
关于Clang报的这个错误,标准里确实有相关的规定,就是:
[class.init#class.base.init-8]
绑定到内存初始值设定项中的引用成员的临时表达式格式错误。
我不确定 Clang 是否理解过度?在我看来,规则似乎是说由mem-initializer 的 mem-initializer-id命名的引用成员不应绑定到临时表达式。在我的示例中,c类的成员Data不是引用。
据推测,Clang可以认为任何使引用成员绑定到临时表达式的引用成员的初始化都发生在成员初始值设定项中都是格式错误的。所以我举了一个例子来检验是否Clang这么认为。
B construct
A destroy
exit
B …Run Code Online (Sandbox Code Playgroud) "15.6.2初始化基础和成员"(N4713)部分在第11项之后有以下示例:
struct A {
A() = default; // OK
A(int v) : v(v) { } // OK
const int& v = 42; // OK
};
A a1; // error: ill-formed binding of temporary to reference
A a2(1); // OK, unfortunately
Run Code Online (Sandbox Code Playgroud)
关于这个例子最后一行的构造有什么不幸?
我在整个参考文献中搜索了其他可能发生的"不幸"行为,但我找不到.
如果在这种特殊情况下不幸,那么它是否可能被视为非法?