6

以下是测试代码:

struct A
{
  operator int ();
  operator int () const;
};

void foo (const int);

现在,在调用时:

foo(A());  // calls A::operator int()

为什么它总是选择非常量版本?即使 makeoperator const int () const;对调用没有任何影响foo()。除了标准参考之外,有人可以从逻辑上解释其背后的原因吗?

4

3 回答 3

13

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 限定符仅影响函数的定义。

于 2011-06-29T03:22:54.993 回答
5

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.,

于 2011-06-29T03:59:19.950 回答
4

关于 C++,您必须记住一条规则:它从不考虑选择重载时返回的值。在这种情况下,由于该operator int函数不接受参数,因此它也不能使用参数列表来缩小选择范围。所有它可以使用它被调用的对象的常量。由于这是一个新的临时对象,它不是 const,所以它不会选择 const 重载。

于 2011-06-29T03:32:52.783 回答