2011-12-16 11 views
16

Quello che mi piacerebbe fare è qualcosa di simile:migliore alternativa a un typedef per un modello di funzione?

template <class DataType> 
DataType myFunc(DataType in) 
{ 
    ... 
} 

typedef myFunc<int> myFunc_i; 

myFunc_i(37); 

... tuttavia, typedef non possono essere utilizzati per funzioni come questo in C++. Quello che mi chiedevo è ... quali sono le alternative preferite dalle persone in questo caso? Gli unici che vengono in mente sono:

1) Basta trattare il caso, e utilizzare sempre myFunc sintassi 2) Creare manualmente una funzione wrapper, cioè

inline int myFunc_i(int in) 
{ 
    return myFunc<int>(in); 
} 

Questo potrebbe funzionare, ma avrebbe il svantaggio di richiedere manutenzione straordinaria, e la possibilità che si otterrebbe fuori sincrono (per esempio, se si cambia la firma della funzione per myFunc).

Pensieri?

+1

Non capisco, perché non basta chiamare la specializzazione direttamente 'myFunc (37); '? –

risposta

1

Uso decltype:

template <class DataType> 
DataType myFunc(DataType in) 
{ 
    ... 
} 

using myFunc_i = decltype(myFunc<int>(0)); 

myFunc_i(37); 
+0

Non funziona davvero! – Silencer

4

Esempio di codice:

#include <iostream> 


template <typename T> 
T sqr(T a){ 
    return a*a; 
} 

auto s = sqr<int>; 
int main() { 

    std::cout<<s(3.9); 
    return 0; 
} 

stampe 9, il che significa che la funzione int
auto utilizzato richiede C++ 0x, è possibile utilizzare vera typename invece, ma è brutto e avrete bisogno di controllo cambiando firma pure. Inoltre, questo codice, potrebbe non consentire il compilatore inline questa funzione

  • Per quanto mi riguarda, è spesso meglio utilizzare il nome completo con <>

  • Nel tuo caso, non è necessario utilizzare <> perché myFunc è sufficiente (DataType possono essere ricevuti dal tipo di argomento)

+0

L'esempio non viene compilato per me ... da "requries C++" volevi dire C++ 0x o microsoft? –

+0

@PaulMolodowitch, intendo C++ 0x, di cource, mi dispiace per la disattenzione – RiaD

14

Prova questo:

typedef int (*myFunc_i_type)(int); 
myFunc_i_type const myFunc_i = &myFunc<int>; 

questo innescherà un errore del compilatore se la firma del myFunc cambia mai. Rendendolo const anche vieta la riassegnazione. puntatori a funzione sono anche richiamabili come qualsiasi normale funzione: myFunc_i(5).

Se non si desidera un errore di compilazione, ma piuttosto avere aggiornarsi, utilizzare auto (di nuovo con const):

auto const myFunc_i = &myFunc<int>; 
5

Alcuni possono non essere d'accordo, alcuni possono scuotere le loro ginocchia contro questo, ma considerare questo opzione:

#define myFunc_i myFunc<int> 

Per quanto riguarda i macro, questo è abbastanza sicuro; l'unico pericolo è che qualcuno potrebbe ridefinire o non definirlo in seguito.

A parte questo, ha tutti i vantaggi di auto const myFunc = myFunc<int>;. Se vuoi auto ma non vuoi ancora usare le funzionalità di C++ 0x, questo è un modo più portabile per ottenere lo stesso effetto.

+0

Questo è ... onestamente, uno degli usi migliori che ho visto per le macro del preprocessore in C++. Può funzionare anche con macro CdC/C++ 11, come ad esempio se si desidera essere in grado di specificare in modo esplicito i parametri del modello di funzione senza doverli digitare ogni volta. Ad esempio, '#define myFunc_allSameType (a, ...) myFunc (a, __VA_ARGS __)' su MSVC o 'myFunc_allSameType #define (a, ...) myFunc (a, ## __ VA_ARGS __)' su GCC. Non sempre utile, ma utile nei casi in cui ci sono molti parametri del modello e sono tutti noti in anticipo o determinati dagli argomenti. –

2

Farei un piccolo miglioramento rispetto alla risposta di Xeo.

Invece di usare:

auto const myFunc_i = &myFunc<int>; 

userei

constexpr auto myFunc_i = &myFunc<int>; 
Problemi correlati