§3.10第9节说“非类别的rvalues总是有cv不合格的类型”。这让我很奇怪......
int foo()
{
return 5;
}
const int bar()
{
return 5;
}
void pass_int(int&& i)
{
std::cout << "rvalue\n";
}
void pass_int(const int&& i)
{
std::cout << "const rvalue\n";
}
int main()
{
pass_int(foo()); // prints "rvalue"
pass_int(bar()); // prints "const rvalue"
}
根据标准,对于非类类型没有const rvalue,但bar()
更喜欢绑定到const int&&
。这是编译器错误吗?
编辑:显然,this
也是一个限制值:)
编辑:这个问题似乎在g ++ 4.5.0中修复,现在两行都打印“rvalue”。
答案 0 :(得分:11)
委员会似乎已经意识到这部分标准存在问题。 CWG issue 690谈到了与标准完全相同的部分有些类似的问题(在2009年9月的“附加说明”中)。我想很快就会为标准的那一部分起草新语言。
编辑:我刚刚在comp.std.c ++上提交了一篇文章,注意到了问题,并为标准的相关部分提出了新的措辞。不幸的是,作为一个受审核的新闻组,几乎每个人都可能在通过那里的审批队列时忘记了这个问题。
答案 1 :(得分:2)
好点。我想有两件事要看:1)当你指出非类rvalue的东西时,2)重载决策是如何工作的:
最佳选择标准 function是参数的数量, 参数与...的匹配程度如何 候选人的参数类型列表 功能,[...]
我没有看到标准中的任何内容告诉我在重载解析期间特别处理非类rvalues。
我的标准草案(N-4411)略有涵盖您的问题:
然而,发挥作用的是参考绑定,隐式转换序列,引用和重载解析的并行读取:
13.3.3.1.4参考绑定
2当参考类型的参数 不直接绑定到参数 表达,转换序列 是将参数表达式转换为底层证书所需的一个 参考类型 到13.3.3.1。
和
13.3.3.2对隐式转化序列进行排名
3两个隐式转换序列 同样的形式是难以区分的 转换序列除非其中之一 以下规则适用:
- 标准转换序列S1是比转换序列更好的转换序列 标准
转换序列S2,如果- S1和S2是参考绑定(8.5.3),两者都不是指 隐式对象参数 非静态 声明没有ref-qualifier的成员函数,并且S1绑定了一个 左值参考 到左值并且S2绑定右值参考或S1绑定右值 引用右值和S2 绑定左值参考。
[例如:
int i;
int f();
int g(const int&);
int g(const int&&);
int j = g(i); // calls g(const int&)
int k = g(f()); // calls g(const int&&)