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