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