Почему этот вызов к шаблону неоднозначен? - PullRequest
0 голосов
/ 02 октября 2018

Я объявляю два шаблона: первый преобразует аргумент x из типа T в тип U, а второй из типа U в тип T.Если я позвоню cast с 10, компилятор не будет жаловаться.Я думаю, что оба отвечают требованиям, которые будут использоваться, и поэтому должна быть неоднозначность, это правда?Этот код печатает 10.

#include <iostream>

template<typename T, typename U>
U cast(T x) {
    return static_cast<U>(x);
}

template<typename T, typename U>
T cast(U x) {
    return static_cast<T>(x);
}

int main() {
    std::cout << cast<int,float>(10) << '\n';
}

Ответы [ 2 ]

0 голосов
/ 02 октября 2018

Когда вы используете cast<int, float>, учитываются оба шаблона.

template<typename T=int,typename U=float>
U cast(T x);
template<typename T=int,typename U=float>
T cast(U x);

, тогда мы подставляем:

template<typename T=int,typename U=float>
float cast(int x);
template<typename T=int,typename U=float>
int cast(float x);

, на данный момент нет типов для вывода.Итак, мы переходим к разрешению перегрузки.

В одном случае мы можем взять int и преобразовать в float при вызове cast, а в другом - intи преобразовать в int, когда вызовет cast.Заметьте, я совсем не смотрю на тело актеров;тело не имеет отношения к разрешению перегрузки.

Второе не преобразование (в точке вызова) является лучшим соответствием, поэтому выбирается перегрузка.

Если вы сделали это:

std::cout << cast<int>(10) << "\n";

вещи становятся более интересными:

template<typename T=int,typename U=?>
U cast(T x);
template<typename T=int,typename U=?>
T cast(U x);

для первого мы не можем вывести U.Для второго мы можем.

template<typename T=int,typename U=?>
U cast(int x);
template<typename T=int,typename U=int>
int cast(int x);

, поэтому здесь у нас есть одна жизнеспособная перегрузка, и она используется.

0 голосов
/ 02 октября 2018

Инстанцирование не является неоднозначным, поскольку аргумент функции в точности соответствует первому параметру шаблона: литерал 10 является int, который также явно указан для первого типа шаблона.

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

// error: call of overloaded 'cast<int, float>(unsigned int)' is ambiguous
std::cout << cast<int,float>(10u) << "\n";
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...