C++ 如果定义转换函数,为什么要显式指定常量限定符?

C++ 如果定义转换函数,为什么要显式指定常量限定符?,c++,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' 编译器抛出一个错误。但该标准规定的是第13.3.3.1.2/1节[over.ics.user]: 用户定义的转换序列由初始标准组成 转换顺序,

在示例中:

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'
编译器抛出一个错误。但该标准规定的是第13.3.3.1.2/1节[over.ics.user]:

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


因此,在本例中,第一个标准转换应将常量B转换为B,然后调用转换函数。但它没有,为什么?它到底是如何工作的?注意:如果我们用操作符A const{return A;}替换操作符A{return A;},那么这个例子就可以很好地工作了。这里您不需要转换序列,就像从标准中选择的那样

您正在调用

B::operator A()
在声明为常量B的对象上

实际上,3.9.1说:

非静态成员函数可以声明为const、volatile或const 不稳定的这些cv限定符影响此指针的类型 9.3.2. 它们还影响构件的功能类型8.3.5 作用声明为const的成员函数是const成员函数

此外,9.3.2/3:

可以对对象表达式调用cv限定成员函数 5.2.5仅当对象表达式为cv限定或 限定的cv小于成员函数

与任何其他方法调用一样,在const对象上运行非const方法调用。这种保护并没有因为显而易见的原因而被破坏


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

没有标准的转换函数可以从常量转换为非常量,标准的转换是从非常量转换为常量const@gsf你为什么不发表你的评论作为回答呢?看起来是对的,没错!我将把参考添加到标准中。