Почему перегрузка функций-членов неявного преобразования работает по типу возвращаемого значения, хотя для обычных функций это не разрешено?

StackOverflow https://stackoverflow.com/questions/1128501

Вопрос

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
}
Это было полезно?

Решение

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

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

Другие советы

Это не возвращаемый тип.Это преобразование типов.

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

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

На самом деле нет технической причины предотвращать перегрузку функций для типов результатов.Это делается, например, в некоторых языках, таких как 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"; }
};

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top