【问题标题】:How come a const temporary chooses to call a non-const member function over a const one? [duplicate]一个 const 临时成员如何选择调用一个非 const 成员函数而不是一个 const 成员函数? [复制]
【发布时间】:2013-05-17 10:58:09
【问题描述】:

示例代码取自:http://en.cppreference.com/w/cpp/types/add_cv (我稍微修改了一下。)

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

在第二次调用中,T 是 const 限定的,所以 T() 应该调用 const 版本,对吗?还是我错过了一些特殊规则?

【问题讨论】:

  • 看起来像 MSVC 中的一个 bug,因为 g++-4.8 和 clang++-3.2 调用了 const 函数。
  • 是的,这是以前出现的错误。 MSVC 在 T() 中忽略 T 的 const 限定符。
  • 语言措辞要求在您的模板中,如果 T 是具有可能 const-volatile 限定的 非类 类型,则在生成 prvalue。似乎 VS 对类类型也使用了相同的逻辑(不正确)
  • @ForEveR 感谢您的评论,我现在明白了。
  • @DavidRodríguez-dribeas 哦,有道理。

标签: c++ visual-c++ visual-studio-2012 const-method


【解决方案1】:

标准中的相关引用是 5.2.3 [expr.type.conv]/2

表达式 T(),其中 T 是非数组完整对象类型或(可能是 cv 限定的)void 类型的简单类型说明符或类型名称说明符,创建指定类型的纯右值,这是值初始化的(8.5;对于 void() 情况没有进行初始化)。 [注意:如果 T 是 cv 限定的非类类型,则在确定结果纯右值 (3.10) 的类型时忽略 cv 限定符。 ——尾注]

标准中的措辞明确提到(以非规范形式)对于 non-class 类型,const-volatile 资格被删除,但在您的情况下,类型是 class ,并且注释不适用。似乎 VS 应用了与非类类型相同的规则。

【讨论】:

  • 感谢您的解释
猜你喜欢
  • 2015-06-10
  • 2016-08-17
  • 2011-06-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多