A()
daje tymczasowy obiekt A
, który nie jest const-kwalifikowany. Wyrażenie A()
jest wyrażeniem rvalue, tak, ale to nie czyni warunku konstelacji obiektu A
.
Ponieważ obiekt A
nie jest const-qualified, niestanowiący operator int()
jest dokładnym dopasowaniem, a const operator int()
wymaga konwersji kwalifikacji, więc nietrwałe przeciążenie jest wybierane jako najlepsze dopasowanie.
Jeśli ma to być const kwalifikowaną, to trzeba wyraźnie zwrócić const wykwalifikowanych A
:
foo(identity<const A>::type());
gdzie identity
jest zdefiniowany jako
template <typename T>
struct identity { typedef T type; };
pamiętać, że istnieje tak naprawdę nie ma różnicy pomiędzy operator const int() const
i operator int() const
: wynikiem jest rwartość i tylko wartości rvalue typu klasy mogą być const-kwalifikowane (int
nie jest typem klasy).
Należy również zauważyć, że nie ma różnicy między void foo(const int)
, którą masz i void foo(int)
. Najwyższe wartości const-qualifiers dla typów parametrów nie mają wpływu na typ funkcji (tj. Typ obu tych deklaracji to void foo(int)
). Między innymi dlatego, że dla dzwoniącego nie ma znaczenia, czy istnieje kwalifikator const najwyższego poziomu; musi wykonać kopię niezależnie. Najwyższy poziom const-qualifier wpływa tylko na definicję funkcji.
Nawet 'A' bycie normalnym stosu/sterty przydzielone obiektu (nie tymczasowego), daje taki sam wynik. – iammilind
Jeśli obiekt nie jest const-kwalifikowany, przeciążenie niestałe jest lepiej pasować podczas przeciążania. Czy jest jakiś powód, dla którego można by się tego spodziewać? –
Dlaczego się mylić, nawet jeśli 'foo()' otrzymuje 'const int' i mamy' const :: operator const int() const; ', nadal idzie i wybiera normalny' A :: operator int' . – iammilind