iam*_*ind 6 c++ overloading const overload-resolution
以下是测试代码:
struct A
{
operator int ();
operator int () const;
};
void foo (const int);
Run Code Online (Sandbox Code Playgroud)
现在,在调用时:
foo(A()); // calls A::operator int()
Run Code Online (Sandbox Code Playgroud)
为什么总是选择非const版本?即使制作operator const int () const;对调用也没有任何影响foo().除了标准参考,有人可以逻辑解释,背后的原因是什么?
Jam*_*lis 13
A()为您提供一个A非const限定的临时对象.该A()表达式是一个右值表达式,是的,但是这并不能使A对象const限定.
由于A对象不是const限定的,因此非const operator int()是精确匹配,const operator int()需要限定转换,因此选择非const重载作为最佳匹配.
如果你想要它是const限定的,你需要显式请求一个const限定的A:
foo(identity<const A>::type());
Run Code Online (Sandbox Code Playgroud)
在哪里identity定义为
template <typename T>
struct identity { typedef T type; };
Run Code Online (Sandbox Code Playgroud)
注意,operator const int() const和之间确实没有区别operator int() const:结果是rvalue,只有class-type rvalues可以是const限定的(int不是类类型).
另请注意void foo(const int),您和之间没有区别void foo(int).参数类型的顶级const限定符不会影响函数的类型(即,这两个声明的类型都是void foo(int)).除其他原因外,这是因为调用者是否存在顶级const限定符并不重要; 无论如何都必须制作副本.顶级const限定符仅影响函数的定义.
James McNellis的回答确实涵盖了这一切,但它并没有伤害(我希望)更多的解释.
所以.
你打电话的时候 …
o.operator int()
Run Code Online (Sandbox Code Playgroud)
...然后过载选择完全取决于.的常数o.
没有其他的.
要了解原因,请考虑以下类:
struct Bar
{
void f() {}
void f() const {}
};
Run Code Online (Sandbox Code Playgroud)
从技术上讲,这些成员函数不需要是成员函数.他们也可以被选为独立的职能.但他们需要Bar争论:
struct Bar
{};
void f( Bar& ) {}
void f( Bar const& ) {}
Run Code Online (Sandbox Code Playgroud)
希望现在你可以更容易地看到它
Bar o;
f( o );
Run Code Online (Sandbox Code Playgroud)
然后可以选择第一个功能.就是这样.因为如果选择了第二个函数,那么你永远不会得到第一个函数.因为如果你制作了这个对象const,那么它就会破坏const正确性以选择第一个.因此,当对象const只能选择第二个时,因此,当它不是const第一个被选中时.
简而言之,这个规则的唯一实际替代方案是始终选择第二个,这将使第一个相当无用,是吗?
干杯&hth.,