2011-06-29 71 views

回答

13

A()为您提供了一个临时A对象不是const限定。该A()表达是一个右值表达式,是的,但是这不会使A对象const限定。

由于A对象不是const限定的,因此非const operator int()完全匹配,const operator int()需要进行限定转换,因此非常量过载被选为最佳匹配。

如果你希望它是const限定的,你需要明确要求常量限定A

foo(identity<const A>::type()); 

其中identity定义为

template <typename T> 
struct identity { typedef T type; }; 

注意,有真operator const int() constoperator int() const之间没有差异:结果是一个右值和唯一的类型右值可以是常量限定(int不是类型)。

另请注意,您所拥有的void foo(const int)void foo(int)之间没有区别。上参数类型顶层常量-限定符不影响功能的类型(即,这两个声明的类型是void foo(int))。除此之外,这是因为调用者是否有顶级const限定符并不重要;无论如何都必须复制一份。顶级const限定符只影响函数的定义。

+0

即使'A'是一个正常的堆叠/堆上分配对象(未暂时的),它给出了相同的结果。 – iammilind

+0

如果该对象不是const限定的,则非重载过载在重载解析期间是更好的匹配。有没有一个理由你会认为这不是这种情况? –

+0

为什么我会感到困惑的是,即使'foo()'接收到'const int'并且我们有一个'A :: operator const int()const'',它仍然会选择正常的'A :: operator int' 。 – iammilind

4

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

+1

* Never *可能太强大;解决超载时会考虑返回类型当函数的地址和解析转换运算符进行自动转换时(当后一种函数需要在返回类型上重载时,后者会非常有用,它会返回一个包含不同转换运算符的代理。) –

5

James McNellis ’答案真的覆盖了一切,但它没有’ t伤害(我希望)更多的解释。

所以。

当你打电话给&hellip;

o.operator int() 

&hellip;那么过载的选择完全取决于的恒定性o

没有别的。

要知道为什么,考虑这个类:

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时,第一个被选中。

总而言之,唯一可行的选择就是总是选择第二个,这会使第一个无用,是吗?

干杯&第h。,

+0

如果将非const版本设为私有版本,它仍会尝试使用该版本而不是公共const版本,从而导致“尝试访问私有成员”错误!很烦人。 – Oktalist

相关问题