C++ 为什么常量临时函数选择调用非常量成员函数而不是常量函数?
示例代码取自: (我稍微修改了一下。)C++ 为什么常量临时函数选择调用非常量成员函数而不是常量函数?,c++,visual-c++,visual-studio-2012,const-method,C++,Visual C++,Visual Studio 2012,Const Method,示例代码取自: (我稍微修改了一下。) 在第二次调用中,T是const限定的,因此T()应该调用const版本,对吗?还是我遗漏了一些特殊规则?标准中的相关引用是5.2.3[expr.type.conv]/2 表达式T(),其中T是非数组完整对象类型或(可能是cv限定的)void类型的简单类型说明符或typename说明符,创建指定类型的prvalue,该值已初始化(8.5;void()情况下未进行初始化)。[注:如果T是cv限定的非类类型,则在确定结果prvalue(3.10)的类型时,cv限
在第二次调用中,
T
是const限定的,因此T()
应该调用const版本,对吗?还是我遗漏了一些特殊规则?标准中的相关引用是5.2.3[expr.type.conv]/2
表达式T(),其中T是非数组完整对象类型或(可能是cv限定的)void类型的简单类型说明符或typename说明符,创建指定类型的prvalue,该值已初始化(8.5;void()情况下未进行初始化)。[注:如果T是cv限定的非类类型,则在确定结果prvalue(3.10)的类型时,cv限定符将被忽略。-结束注]
本标准中的措辞明确提到(以非规范性形式)对于非类类型,删除常量volatile限定,但在您的情况下,该类型为类,注释不适用。VS似乎应用了与非类类型相同的规则。看起来像MSVC中的一个bug,因为g++-4.8和clang++-3.2调用了const函数。是的,这是以前出现过的bug。MSVC忽略
T()
中T
的常量限定符。语言措辞要求在模板中,如果T
是非类类型且可能具有常量volatile限定符,则在生成prvalue时会删除该限定符。似乎VS对类类型也使用了相同的逻辑(错误)@永远谢谢你的评论,我现在明白了。@DavidRodríguez dribeas哦,这很有意义。谢谢你的解释
struct foo
{
void m() { std::cout << "Non-cv\n"; }
void m() const { std::cout << "Const\n"; }
};
template<class T>
void call_m()
{
T().m();
}
int main()
{
call_m<foo>();
call_m<const foo>(); //here
}
Non-cv
Non-cv