【问题标题】:Temporary const array not binding to rvalue reference临时 const 数组未绑定到右值引用
【发布时间】:2013-07-04 17:26:33
【问题描述】:

我有以下测试程序:

#include <iostream>
#include <type_traits>
#include <utility>

template<typename Ty, std::size_t N>
void foo(Ty (&&)[N])
{
    std::cout << "Ty (&&)[" << N << "]\t" << std::is_const<Ty>::value << '\n';
}

template<typename Ty, std::size_t N>
void foo(Ty (&)[N])
{
    std::cout << "Ty (&)[" << N << "]\t" << std::is_const<Ty>::value << '\n';
}

template<typename Ty>
using id = Ty;

int main()
{
    std::cout.setf(std::cout.boolalpha);

    foo(id<int[]>{1, 2, 3, 4, 5});
    foo(id<int const[]>{1, 2, 3, 4, 5}); // <-- HERE.
    int xs[]{1, 2, 3, 4, 5};
    foo(xs);
    int const ys[]{1, 2, 3, 4, 5};
    foo(ys);
    foo(std::move(xs));
    foo(std::move(ys));
}

我希望标有箭头的行会调用右值重载,就像它上面的非常量调用一样,但事实并非如此。

这只是 GCC 中的一个错误,还是标准中的某些内容导致选择了左值重载?

【问题讨论】:

  • 有趣,Clang 得到了正确的结果并调用了右值重载。
  • 好问题:我对标准的天真理解与您的一致。 Live 如果您想查看输出。
  • 这里发生了一些有趣的事情:ideone.com/ptTJ8i -- 我的 const int 临时被视为 int&amp;&amp;,而不是 const int&amp;&amp;
  • @Yakk 没有“const int temporaries”。 “const int”类型的右值不存在,因为 const 和 volatile 仅对对象有意义。非类/非数组类型的右值不引用对象,因此标准规定对于这样的右值,“const”和“volatile”总是不存在的。出于同样的原因,没有“int temporaries”:临时对象是其生命周期很快停止的对象。但是像 "0" 或 "int()" 这样的右值 int 并不引用对象,因此没有生命周期可以停止。因此,规范并没有说它们是临时的(但在一个地方有一个错误说)。
  • @JohannesSchaub-litb:我不明白。如果“不存在const int 类型的右值”,那么const int&amp;&amp; 到底是什么?

标签: c++ arrays c++11 constants rvalue-reference


【解决方案1】:

按照标准§12.2 [class.temporary]

类类型的临时对象是在各种上下文中创建的:绑定一个 引用纯右值(8.5.3),返回纯右值(6.6.3), 创建纯右值(4.1、5.2.9、5.2.11、5.4)的转换,抛出 异常 (15.1),进入处理程序 (15.3),并且在某些情况下 初始化 (8.5)。

所以id&lt;int const[]&gt;{1, 2, 3, 4, 5} 是临时的,因此是prvalue §3.10 [basic.lval]

一个右值(历史上所谓的,因为右值可能出现在 赋值表达式的右侧)是一个 xvalue,a 临时对象 (12.2) 或其子对象,或不是 与对象相关联。

prvalue(“纯”右值)是不是 xvalue 的右值。

因此应选择带有右值引用参数的重载函数。

【讨论】:

  • 所以基本上这是 GCC 的一个错误?
  • @Mehrdad:我想是的。正如 Xeo 在他的评论中指出的那样,Clang 是正确的。
猜你喜欢
  • 2021-09-09
  • 1970-01-01
  • 2010-11-21
  • 1970-01-01
  • 2017-04-13
  • 2019-07-02
  • 2017-04-15
  • 2015-04-02
  • 2017-03-12
相关资源
最近更新 更多