Тип автоматичного повернення шаблону та неоднозначності


20

У мене функція шаблону перевантажена:

template<typename T1, typename T2>
auto overMax(T1 a, T2 b)
{
    std::cout << __FUNCSIG__ << std::endl;

    return b < a ? a : b;
}

template<typename RT, typename T1, typename T2>
RT overMax(T1 a, T2 b)
{
    std::cout << __FUNCSIG__ << std::endl;

    return b < a ? a : b;
}

Якщо я називаю це так:

auto a = overMax(4, 7.2); // uses first template
auto b = overMax<double>(4, 7.2); // uses second template

все працює ідеально, але

auto c = overMax<int>(4, 7.2); // error

викликає неоднозначний дзвінок.

Чому так з int , і добре, які інші типи?


4
Я думаю , що ... .... То , як компілятор бачить, це: з int, ви вказавши typename RTабо typename T1? Оскільки 4також є int, може бути будь-яким. З double, безпосередньо4 не відповідає типу , тому переважніше друге перевантаження. double
ChrisMM

Для мене це виглядає трохи хитро, тому що ви перевантажуєте тип повернення, але з шаблонами, які мають різну кількість параметрів.
Боргледер

Відповіді:


25

RTне виводиться, тому, не надаючи його, template<typename T1, typename T2> auto overMax(T1 a, T2 b)можна лише зателефонувати.

Коли ви (частково) надаєте один аргумент шаблону, обидва способи є життєздатними,

але залежно від аргументу, може бути кращим кандидатом:

  • Для auto b = overMax<double>(4, 7.2); // uses second template

    І те overMax<double, int, double>й overMax<double, double>інше є життєздатним.
    Але overMax<double, int, double>це точний збіг ,
    тоді як overMax<double, double>потрібно intдля doubleперетворення.

  • Для auto c = overMax<int>(4, 7.2); // Ambiguous call

    І те overMax<int, int, double>й overMax<int, double>інше є життєздатним.
    Але жоден з них не є кращим або більш спеціалізованим, тому дзвінок неоднозначний.


чому жоден із них не кращий? Я правий, що в кулаковому випадку overMax <int> (4, 7.2); призведе до перетворення 7,2 в int . А у другому випадку повернутий результат, який спочатку подвійний , буде перетворений на int завдяки явній <int> ?
підсилювач

1
@ підсилювач: overMax<int>(4, 7.2)буде в першому випадку T1=int(надається), T2=double(виведено), а в другому випадку RT=int(надається), T1=int, T2=double(виведено). Визначення вмісту обох методів не використовується для вибору перевантаження.
Jarod42

як на мене, другий випадок підходить, оскільки є перетворення типу повернення для першого, а перетворення взагалі для другого, чи не так?
підсилювач

хммм ... перетворення типу повернення не грає ролі ... тоді, так, обидва виклики рівнозначні з цієї точки зору
підсилювач
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.