2016-02-09 8 views
7

Esiste un modo per chiamare il funtore operator()(int) di un modello di classe Foo come mostrato di seguito (online version)Chiamare un funtore su modelli in un modello di classe

template<typename T> 
struct Foo 
{ 
    template<typename U> 
    void operator()(int) 
    { 
    } 
}; 

int main(int argc, char *argv[]) 
{ 
    Foo<char> foo; 
    foo<bool>(42); 
} 

sto ottenendo il messaggio di errore in GCC 4.9. 3

error: expected primary-expression before ‘bool’ 
    foo<bool>(42); 

avrei anteporre funtore con template se la funzione membro non era un funtore ed era prefisso ::, . o ->. Senza alcun aiuto il compilatore non potrebbe sapere come analizzare questa espressione; come funtore o istanziazione di un oggetto anonimo di tipo foo<int>.

risposta

5

Funzionerebbe con;

foo.operator()<bool>(42); 

Operatori giocano meglio con i tipi di modello di argomenti dedotti.

Non si forniscono dettagli sufficienti del contesto in cui viene utilizzato, come alternative che è possibile prendere in considerazione;

  • rendendo l'operatore di call una funzione membro e permettere così espliciti tipo di modello argomenti
  • un meccanismo tag dispaccio
  • accettare il tipo U come argomento

Per esempio;

template<typename U> 
void operator()(int, U&& /*initial*/) 
{ 
    // use the initial value of U 
} 
// called as... 

foo(42, true); // U is bool in your example 

O semplicemente la funzione membro;

template<typename U> 
void my_func(int) 
{ 
} 
// called as... 

foo.my_fun<bool>(42); 
+0

"Gli operatori giocano meglio con i tipi di argomenti del modello dedotti" - vale la pena ricordare. Ho omesso il '&&' però. – Olumide

+0

@Olumide. L'argomento 'U &&' viene usato solo con l'idea che se il tipo fosse più complesso di una primitiva, si potrebbe usare un 'std :: move' o 'U &&' può anche legarsi ad un temporaneo. Un semplice 'U' funzionerebbe anche bene. – Niall

5

Sì, ma è brutto:

foo.operator()<bool>(42); 
3

Purtroppo avresti bisogno di utilizzare foo.operator()<bool>(42); per questo. foo<bool> è valido per cose come i modelli di variabili C++ 14, non per gli operatori di chiamata modello.

Che cosa si potrebbe fare è il tipo di tag e passare che come argomento per l'operatore di call di dedurre il tipo giusto:

//tag 
template <typename T> 
struct type{}; 

template<typename T> 
struct Foo 
{ 
    template<typename U> 
    //deduction on the tagged type 
    void operator()(type<U>, int) 
    { 
    } 
}; 

int main(int argc, char *argv[]) 
{ 
    Foo<char> foo; 
    foo(type<bool>{}, 42); 
    // ^^^^^^^^^^^^ pass tag 
} 

si potrebbe fare di questo un po 'più bello utilizzando C++ 14 modelli variabili per il tag:

template <typename T> 
struct type_t{}; 

//variable template for nicer usage 
template <typename T> 
type_t<T> type; 

template<typename T> 
struct Foo 
{ 
    template<typename U> 
    void operator()(type_t<U>, int) 
    { 
    } 
}; 

int main(int argc, char *argv[]) 
{ 
    Foo<char> foo; 
    foo(type<bool>, 42); 
    //don't need {}^ 
} 
Problemi correlati