【问题标题】:Uniform initialization of references引用的统一初始化
【发布时间】:2011-07-01 10:01:13
【问题描述】:

我目前正在尝试了解 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 &amp;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 来启用英文错误消息。
  • gcc 版本:4.6.1

【问题讨论】:

  • gcc 4.4.1 也不编译第一个示例:uniform_init_of_ref.cpp:3: error: ISO C++ forbids use of initializer list to initialize referen ce 'ref'
  • @rmflow: gcc4.4 没有完全实现统一初始化。
  • 你可以在你的构造函数初始化列表中使用普通的x(xx),据我所知不需要那些新奇的统一的东西:-)
  • @alf-p-steinbach 是的,但我想避免在构造函数中使用相同样式的初始化,而不根据必须初始化的内容更改样式。
  • @evnu:其实我认为抱怨是正确的,因为如果我正确阅读N2672,不应该允许以这种方式初始化对非常量对象的左值引用,无论它们是否是原始的或类类型。

标签: c++ c++11 g++ reference uniform-initialization


【解决方案1】:

根据N2672 第8.5.4.4 段应该说:

否则,如果 T 是引用类型,则 T 引用的类型的右值临时是列表初始化的,并且引用绑定到该临时。 [注意:像往常一样,如果引用类型是对非常量类型的左值引用,则绑定将失败并且程序格式错误。 ]

这(如果我理解正确的话)意味着引用的统一初始化将它们绑定到新的匿名实例,所以在我看来这没什么用。这仍然不能解释为什么一个有效而另一个无效;它们的行为应该相同(除非Y 有一些明确的构造函数)。

【讨论】:

  • 所以在第一个示例中,执行ref = 42不会修改a
  • @alexandre-c 在第一个示例中分配给ref 会在此处更改a 的值。
  • @evnu:这种行为不符合@Jan 引用的内容。你和 Comeau 确认过吗?
  • @alexandre-c Comeau 在第一个示例中抛出错误。我会更新我的答案。
  • 这和 n3290 说的差不多,只是它使用 prvaluetemporary 而不是 rvaluetemporary
猜你喜欢
  • 2012-05-17
  • 2020-03-18
  • 1970-01-01
  • 1970-01-01
  • 2019-11-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多