我目前正在尝试理解C ++ 0x的新统一初始化。不幸的是,我对使用引用的统一初始化感到困惑。例如:
int main() {
int a;
int &ref{a};
}
这个例子很好用:
% LANG=C g++ uniform_init_of_ref.cpp -std=c++0x -o uni -Wall -Wextra
uniform_init_of_ref.cpp: In function `int main()':
uniform_init_of_ref.cpp:3:10: warning: unused variable `ref' [-Wunused-variable]
(更新 Comeau会针对该示例抛出错误,因此gcc也不应该编译它)
现在,如果我使用自定义数据类型而不是整数,它将不再起作用:
class Y
{};
int main()
{
Y y;
Y &ref{y};
}
% LANG=C g++ initialization.cpp -std=c++0x -o initialization -Wall -Wextra
initialization.cpp: In function `int main()':
initialization.cpp:9:13: error: invalid initialization of non-const reference of type `Y&' from an rvalue of type `<brace-enclosed initializer list>'
initialization.cpp:9:8: warning: unused variable `ref' [-Wunused-variable]
不幸的是,我没有在标准草案中找到相关部分。我的猜测是我误解了统一初始化的用法,因为Comeau抱怨这条消息:
ComeauTest.c(9): error: reference variable "ref" requires an initializer
Y &ref{y};
那么,有人可以指出我正确的方向吗?
如果你想知道为什么这个问题是相关的,为什么我不只是使用Y &ref(y)
:我希望能够在构造函数的初始化列表中使用统一初始化:
class X { };
class Y {
const X& x;
public:
Y (const X& xx):
x{xx}
{}
};
int main () {
X x;
Y y{x};
}
此操作失败并显示与上述相同的错误消息。
注意:
LANG=C
启用英语错误消息。答案 0 :(得分:6)
根据N2672,第8.5.4.4段应该说:
否则,如果T是引用类型,则由T引用的类型的rvalue临时值被列表初始化,并且引用绑定到该临时值。 [注意:像往常一样,如果引用类型是非const类型的左值引用,则绑定将失败并且程序格式错误。 ]
(如果我理解正确的话)意味着引用的统一初始化将它们绑定到新的匿名实例,所以在我看来它是相当无用的。这仍然无法解释为什么一个有效,另一个没有;它们应该表现相同(除非Y
有一些显式构造函数)。