以下是测试代码:
struct A
{
operator int ();
operator int () const;
};
void foo (const int);
现在,在调用时:
foo(A()); // calls A::operator int()
为什么它总是选择非常量版本?即使生成operator const int () const;
也不会对调用foo()
产生任何影响。除了标准参考之外,有人能合乎逻辑地解释它背后的原因吗?
A()
为您提供了一个非常量限定的临时A
对象。是的,A()
表达式是一个右值表达式,但这不会使A
对象常量限定。
由于A
对象不是const限定的,因此非常量operator int()
是精确匹配,而常量operator int()
需要限定转换,因此选择非常量重载作为最佳匹配。
如果您希望它是const限定的,您需要显式地请求一个const限定A
:
foo(identity<const A>::type());
其中identity
被定义为
template <typename T>
struct identity { typedef T type; };
注意,operator const int() const
和operator int() const
之间实际上没有区别:结果是一个右值,并且只有类类型的右值可以是const限定的(int
不是类类型)。
还要注意,您拥有的void foo(const int)
和void foo(int)
之间没有区别。参数类型上的顶级常量限定符不会影响函数的类型(即,这两个声明的类型都是void foo(int)
)。除其他原因外,这是因为是否存在顶级const限定符对调用者来说并不重要;不管怎样,它都必须复印一份。顶级const限定符只影响函数的定义。
James McNellis’答案确实涵盖了所有内容,但事实并非如此;(我希望)多做一些解释。
所以。
当您呼叫…
o.operator int()
…则过载选择完全取决于CCD_ 18的常数。
没有别的。
要了解原因,请考虑以下类别:
struct Bar
{
void f() {}
void f() const {}
};
从技术上讲,这些成员职能不一定是成员职能。他们也可以被选为独立的职能部门。但他们需要Bar
论点:
struct Bar
{};
void f( Bar& ) {}
void f( Bar const& ) {}
希望现在,当你进行时,更容易看到这一点
Bar o;
f( o );
则可以选择第一个函数。事实的确如此。因为如果选择了第二个函数,那么你就永远无法获得第一个。因为如果您将对象设为const
,那么选择第一个对象将破坏const
的正确性。因此,当对象是const
时,只能选择第二个,因此,当不是const
时,选择第一个。
简言之,这个规则的唯一实用替代方案是总是选择第二个,这会使第一个变得毫无用处,是吗?
干杯&hth。,
关于C++,您必须记住的一条规则是:它从不在选择重载时考虑返回的值。在这种情况下,由于operator int
函数不接受参数,因此也不能使用参数列表来缩小选择范围。它所能使用的就是从中调用它的对象的常量。由于这是一个新的临时对象,它不是const,所以它不会选择const重载。