C++ 带有ref限定符的重载解析
在处理ref限定函数重载时,我从GCC(4.8.1)和Clang(2.9和trunk)中得到了不同的结果。考虑下面的代码:C++ 带有ref限定符的重载解析,c++,c++11,overloading,language-lawyer,ref-qualifier,C++,C++11,Overloading,Language Lawyer,Ref Qualifier,在处理ref限定函数重载时,我从GCC(4.8.1)和Clang(2.9和trunk)中得到了不同的结果。考虑下面的代码: #include <iostream> #include <utility> struct foo { int& bar() & { std::cout << "non-const lvalue" << std::endl; return _bar; }
#include <iostream>
#include <utility>
struct foo
{
int& bar() &
{
std::cout << "non-const lvalue" << std::endl;
return _bar;
}
//~ int&& bar() &&
//~ {
//~ std::cout << "non-const rvalue" << std::endl;
//~ return std::move(_bar);
//~ }
int const& bar() const &
{
std::cout << "const lvalue" << std::endl;
return _bar;
}
int const&& bar() const &&
{
std::cout << "const rvalue" << std::endl;
return std::move(_bar);
}
int _bar;
};
int main(int argc, char** argv)
{
foo().bar();
}
#包括
#包括
结构foo
{
int&bar()&
{
std::cout首先,根据13.3.1.4,隐式对象参数被视为正常参数:
对于非静态成员函数,隐式对象参数的类型为
-对于不使用ref限定符或使用&ref限定符声明的函数,“对cv X的左值引用”
-使用&&ref限定符声明的函数的“对cv X的右值引用”
其中,X是该函数所属的类别,cv是该成员的cv资格
函数声明
因此,您的问题相当于以下内容:
void bar(foo&);
void bar(foo&&);
void bar(const foo&);
void bar(const foo&&);
int main()
{
bar(foo());
}
表达式foo()
是一个类值
其次,非常量左值引用版本是不可行的,因为prvalue不能绑定到它
这就给我们留下了三个解决过载问题的可行函数
每个都有一个隐式对象参数(const foo&
、foo&
或const foo&&
),因此我们必须对这三个参数进行排序,以确定最佳匹配
在这三种情况下,它都是直接绑定的引用绑定。这在declarators/initialization(8.5.3)中有描述
三种可能绑定(const-foo&
、foo&
和const-foo&
)的排名如13.3.3.2.3所述:
标准转换序列S1是比标准转换序列S2更好的转换序列
- S1和S2都是引用绑定,都不引用未声明ref限定符的非静态成员函数的隐式对象参数[此异常不适用于此处,它们都有ref限定符],S1将右值引用绑定到右值。[class prvalue是右值]和S2绑定左值引用
这意味着foo&
和const foo&
都比const foo&
好
- S1和S2是引用绑定,引用所引用的类型除了顶级cv限定符外都是相同的类型,并且由S2初始化的引用所引用的类型比由S1初始化的引用所引用的类型更符合cv限定
这意味着foo&
优于const foo&
所以Clang是对的,它是GCC中的一个bug。foo().bar()
的重载排名如下:
struct foo
{
int&& bar() &&; // VIABLE - BEST (1)
int const&& bar() const &&; // VIABLE - (2)
int const& bar() const &; // VIABLE - WORST (3)
int& bar() &; // NOT VIABLE
int _bar;
};
GCC中的错误似乎完全适用于隐式对象参数(使用ref限定符
),对于一个普通参数,它似乎得到了正确的排名,至少在4.7.2中是这样。右值引用在所有情况下都是更好的匹配。这可能是GGC的ref限定符的一个错误。此外,可能是相关的。;)谢谢你的详细回答。我希望我能多次投票!