在示例中:
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),初始标准转换序列转换源 键入转换函数的隐式对象参数。
因此,在示例中,第一个标准转换应该const B
转换为B
,然后调用转换函数。但它没有,为什么?它是如何工作的?请注意,如果我们将operator A(){ return A(); }
替换为operator A() const{ return A(); }
答案 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方法调用。由于显而易见的原因,这种保护不会被打破。
顺便说一句,看来你自己回答了这个问题。否则,希望这会有所帮助。