如果我们定义转换函数,为什么要明确指定const限定符?

时间:2014-12-07 05:45:04

标签: c++

在示例中:

struct A{ };

struct B
{
    B(){ };
    operator A(){ return A(); }
};

const B b;

void foo(A){ };

int main(){ foo(b); } //error: no matching function for call to 'foo'

DEMO

编译器抛出错误。但标准所说的是(13.3.3.1.2/1 [over.ics.user]}部分:

  

用户定义的转换序列由初始标准组成   转换序列后跟用户定义的转换(12.3)   然后是第二个标准转换序列。 [...]   如果转换函数指定了用户定义的转换   (12.3.2),初始标准转换序列转换源   键入转换函数的隐式对象参数。

因此,在示例中,第一个标准转换应该const B转换为B,然后调用转换函数。但它没有,为什么?它是如何工作的?请注意,如果我们将operator A(){ return A(); }替换为operator A() const{ return A(); }

,该示例将正常工作

1 个答案:

答案 0 :(得分:-1)

此处不要求转换序列,例如您从标准中选择的转换序列。

您正在调用

B::operator A()

在声明为" const B"。

的对象上

实际上,3.9.1说:

  

非静态成员函数可以声明为const,volatile或const   易挥发。这些cv限定符会影响this指针的类型   (9.3.2)。它们还会影响成员的函数类型(8.3.5)   功能;声明const的成员函数是一个const成员函数

此外9.3.2 / 3:

  

可以在object-expression上调用cv限定的成员函数   (5.2.5)仅当object-expression为cv-qualified或者   比成员函数更少的cv资格。

与任何其他方法调用一样,您将在const对象上运行非const方法调用。由于显而易见的原因,这种保护不会被打破。

顺便说一句,看来你自己回答了这个问题。否则,希望这会有所帮助。