Почему неявные функции-члены преобразования, перегружающие работу, возвращают тип, в то время как это не разрешено для нормальных функций? - PullRequest
6 голосов
/ 15 июля 2009

C ++ не допускает полиморфизм для методов, основанных на их типе возврата. Однако при перегрузке неявной функции-члена преобразования это представляется возможным.

Кто-нибудь знает почему? Я думал, что операторы обрабатываются как методы внутри.

Редактировать: Вот пример:

struct func {
    operator string() { return "1";}
    operator int() { return 2; }
};

int main( ) {
    int x    = func(); // calls int version
    string y = func(); // calls string version
    double d = func(); // calls int version
    cout << func() << endl; // calls int version
}

Ответы [ 4 ]

11 голосов
/ 15 июля 2009

Операторы преобразования на самом деле не считаются различными перегрузками, и они не вызываются на основании их типа возврата . Компилятор будет использовать их только тогда, когда он должен (когда тип несовместим и должен быть преобразован) или когда явно предложено использовать один из них с оператором приведения.

Семантически, ваш код делает объявление нескольких различных операторов преобразования типов и не перегрузок одного оператора .

3 голосов
/ 15 июля 2009

Это не тип возврата. Это преобразование типов.

Обратите внимание: func () создает объект типа func. Нет никакой двусмысленности относительно того, какой метод (конструктор) будет вызван.

Единственный вопрос, который остается, заключается в том, можно ли привести его к желаемым типам. Вы предоставили компилятору соответствующее преобразование, так что он рад.

1 голос
/ 15 июля 2009

Не существует технической причины для предотвращения перегрузки функций в типах результатов. Это делается в некоторых языках, таких как, например, Ada, но в контексте C ++, который также имеет неявные преобразования (и два вида их), утилита уменьшается, и взаимодействия обеих функций быстро приводят к неоднозначностям.

Обратите внимание, что вы можете использовать тот факт, что неявные преобразования определяются пользователем для имитации перегрузки типа результата:

class CallFProxy;
CallFProxy f(int);

class CallFProxy {
   int myParameter;
   CallFProxy(int i) : myParameter(i) {}
public:
   operator double() { std::cout << "Calling f(int)->double\n"; return myParameter; }
   operator string() { std::cout << "Calling f(int)->string\n"; return "dummy"; }
};
0 голосов
/ 15 июля 2009

Разрешение перегрузки выбирает между несколькими функциями-кандидатами. В этом процессе возвращаемый тип кандидатов действительно не учитывается. Однако в случае операторов преобразования «тип возврата» является критически важным для определения того, является ли этот оператор кандидатом вообще.

...