2009-12-17 14 views
14

Perché questa deduzione di tipo automatico è possibile solo per le funzioni e non per le classi?Tipo di modello deduzione in C++ per Class vs Function?

+0

fa a parlare di 'std :: vector un (1, true); 'o riguardo' std :: vector v = std :: vector (1, vero); '? Il primo sarà una deduzione "vera", mentre il secondo richiederà un argomento già noto. Notare la complicazione della specializzazione esplicita di bool-vector. –

+0

Il primo, vera deduzione, è che non è possibile? – yesraaj

+0

Ho appena trovato il ragionamento di Bjarne Stroustrups per non averlo incluso nella lingua. –

risposta

17

In casi specifici, si può sempre fare come std::make_pair:

template<class T> 
make_foo(T val) { 
    return foo<T>(val); 
} 

EDIT: Ho appena trovato la seguente in "The C++ Programming Language, Third Edition", a pagina 335. Bjarne dice:

Si noti che gli argomenti del modello di classe sono mai dedotti. Il motivo è che la flessibilità di fornita da diversi costruttori per una classe renderebbe impossibile la detrazione di in molti casi e oscuri in molti altri.

Questo è ovviamente molto soggettivo. C'è stata una discussione su questo in comp.std.c++ e il consenso sembra essere che non c'è motivo per cui non possa essere supportato. Se sia una buona idea o meno è un'altra domanda ...

+0

Questo è quello che ti sto chiedendo perché avresti bisogno di racchiudere una classe all'interno di una funzione, come fanno in boost :: bind – yesraaj

+1

La flessibilità fornita da diversi costruttori non è inferiore o superiore alla flessibilità fornita da diversi sovraccarichi. – Puppy

1

Penso che la conversione di tipo implicita sia applicabile solo agli argomenti di funzione, in modo che il compilatore possa dedurlo per fare in modo che la funzione chiami correttamente.

Ma come si può dedurre di che tipo si vuole avere classe.

Dobbiamo aspettare 4 giorni in cui abbiamo compilatore basato su AI per leggere le nostre menti.

+9

-1 Per quanto ne so, i poteri psichici non fanno parte di nessun programma di ricerca AI. Inoltre, mentre riconosco che l'inglese non è la prima lingua di tutti, l'abuso di "4" è imperdonabile. –

+0

+1 ha detto attendere i giorni in cui i compilatori possono "sapere cosa stai cercando di fare" ed essere molto affidabili ... è una possibilità. Basta aggiungere una bandiera al makefile. –

+0

Nessuna AI necessaria - GCC7 sostiene il supporto per la deduzione degli argomenti del modello per i modelli di classe: https://gcc.gnu.org/projects/cxx-status.html http://www.open-std.org/jtc1/sc22/wg21 /docs/papers/2016/p0091r3.html Quindi aspetta un po 'più a lungo. ;) – Xupicor

4

In caso di una chiamata di funzione, il compilatore deduce il tipo di modello dal tipo di argomento. Ad esempio la funzione std::max. Il compilatore utilizza il tipo di argomenti per dedurre il parametro del modello. Questo non funziona sempre, poiché non tutte le chiamate sono ambigui.

int a = 5; 
float b = 10; 

double result1 = std::min(a, b); // error: template parameter ambigous 
double result2 = std::min<double>(a, b); // explicit parameter enforces use of conversion 

In caso di una classe modello, che non può essere sempre possibile. Prendete per esempio questa classe:

template< class T> 
class Foo { 
public: 
    Foo(); 
    void Bar(int a); 
private: 
    T m_Member; 
}; 

Il tipo T non appare mai in qualsiasi chiamata di funzione, in modo che il compilatore non ha alcun accenno a tutti, che tipo dovrebbe essere usato.

+0

Quindi non è sempre possibile, ma, come si fa notare, non lo è per le funzioni. Quindi questo non spiega veramente perché non è supportato. –

+0

Non so perché non sia supportato (sarebbe ipotizzabile una soluzione best-effort), ma la domanda era, se possibile. Penso di aver risposto, quindi non capisco il downvote. –

+0

Penso che abbia chiesto * perché * non è possibile, non * se * è possibile. –

9

A Kona meeting Template parametro deduzione per i costruttori (P0091R0) è stato approvato, il che significa che in C++ 17 saremo in grado di scrivere:

pair p1{"foo"s, 12}; 
auto p2 = pair{"foo"s, 12}; 
f(pair{"foo"s, 12});