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.