2015-03-06 3 views
6

ho cercato di utilizzare template per il sovraccarico di operatore di chiamata di funzione come nel seguente programma:C++ modello per la funzione di chiamata operatore

#include <stdio.h> 

struct Apple 
{ 
    template <typename tn> tn value(); 
    template <typename tn> tn operator()(); 
}; 

template <> int Apple::value() 
{ 
    return 10; 
} 

template <> int Apple::operator()() 
{ 
    return 10; 
} 

int main() 
{ 
    Apple apple; 
    printf("Value : %d\n", apple<int>()); 
    printf("Value : %d\n", apple.value<int>()); 
    return 0; 
} 

Mentre funzione di valore chiamata nella seconda stampa non mostra alcun errore l'operatore di funzione di chiamata il primo errore mostra stampa expected primary-expression. Non so cosa sto sbagliando. Qualcuno può aiutarmi a conoscere il problema grazie in anticipo.

risposta

10

Il problema si verifica quando si richiama un modello operator() (seconda riga di main()). Nel tuo caso, è necessario specificare esplicitamente il tipo di ritorno, in quanto non può essere dedotto, e il modo corretto di farlo è:

printf("Value : %d\n", apple.operator()<int>()); 

operator()() è una funzione membro modello che prende () come parametri. Quindi, il suo nome è operator(), il suo elenco di parametri è (). Pertanto, per fare riferimento ad esso, è necessario utilizzare apple.operator() (il suo nome), seguito da <int> (parametro del modello), seguito da () (elenco parametri). Sostituisci mentalmente il nome operator() con FUNCTION, quindi operator()() è FUNCTION() e vedrai il modello. Nel tuo caso, apple<int>() sta invocando un modello non operator()() su un oggetto di istanza modello apple<int>, ad esempio apple<int>.operator()(), che non è quello che desideri.

Utile per definire un simile operatore? Probabilmente no, in quanto porta a una brutta sintassi.


È possibile ottenere quello che probabilmente si desidera utilizzando auto ritorno digitare in C++ 14, come

#include <stdio.h> 

struct Apple 
{ 
    template <typename tn> tn value(); 
    auto operator()(); 
}; 

template <> int Apple::value() 
{ 
    return 10; 
} 

auto Apple::operator()() // not a template anymore, return type is deduced int 
{ 
    return 10; 
} 

int main() 
{ 
    Apple apple; 
    printf("Value : %d\n", apple()); 
    printf("Value : %d\n", apple.value<int>()); 
    return 0; 
} 

In questo esempio, auto in realtà non brillano, come si può specificare manualmente int come il tipo di ritorno, ma in dichiarazioni più complicate può essere davvero utile.

+0

ottima risposta che ti ha aiutato a ringraziarti. posso sapere perché la chiamata non può essere dedotta – Dinesh

+0

@Dinesh, l'unico modo per dedurre un tipo è di abbinarlo con qualche espressione. Nel tuo caso, nel sito di chiamata non esiste alcuna espressione contro cui confrontarsi. – vsoftco

+0

sì ma ho specificato il tipo esplicitamente in entrambi i casi e non riesco a capire perché l'errore è solo nella funzione di sovraccarico dell'operatore chiamata – Dinesh