Tipo di ritorno automatico di modello e ambiguità


20

Ho una funzione di template sovraccarico:

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;
}

Se lo chiamo così:

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

tutto funziona perfettamente, ma

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

provoca una chiamata ambigua.

Perché è così con int e OK quali altri tipi?


4
Penso che ... .... Il modo in cui il compilatore lo vede è: con int, stai specificando il typename RTo il typename T1? Poiché 4è anche un int, potrebbe essere uno dei due. Con double, 4non corrisponde direttamente al tipo double, quindi è preferibile il secondo sovraccarico.
ChrisMM,

Questo mi sembra un po 'complicato perché stai sovraccaricando il tipo di ritorno ma con modelli che hanno una quantità diversa di parametri.
Borgleader

Risposte:


25

RTnon è deducibile, quindi quando non lo si fornisce, template<typename T1, typename T2> auto overMax(T1 a, T2 b)può essere chiamato solo.

Quando fornisci (parzialmente) un argomento modello, entrambi i metodi sono vitali,

ma a seconda dell'argomento, si può essere un candidato migliore:

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

    Entrambi overMax<double, int, double>e overMax<double, double>sono vitali.
    Ma overMax<double, int, double>è corrispondenza esatta
    , mentre overMax<double, double>richiede intalla doubleconversione.

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

    Entrambi overMax<int, int, double>e overMax<int, double>sono vitali.
    Ma nessuno dei due è una partita migliore o più specializzata, quindi la chiamata è ambigua.


perché nessuno dei due è molto meglio? Ho ragione che nel primo caso overMax <int> (4, 7.2); causerebbe la conversione di 7.2 in int . E nel secondo caso il risultato restituito, che inizialmente è doppio , verrebbe convertito in int a causa di <int> esplicito ?
amplificatore

1
@amplificatore: overMax<int>(4, 7.2)sarebbe nel primo caso T1=int(fornito), T2=double(dedotto) e nel secondo caso RT=int(fornito), T1=int, T2=double(dedotto). La definizione del contenuto di entrambi i metodi non viene utilizzata per selezionare il sovraccarico.
Jarod42,

per quanto mi riguarda, il secondo caso è adatto, poiché esiste una conversione del tipo restituito per il primo e nessuna conversione per il secondo, non è vero?
amplificatore

hmmm ... la conversione del tipo di ritorno non ha un ruolo ... quindi, sì, entrambe le chiamate sono equivalenti da questo punto di vista
amplificatore
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.