C ++ detrazione del “puntatore non il tipo di funzione” parametri del modello di classe

StackOverflow https://stackoverflow.com/questions/368737

Domanda

Si consideri una classe template come:

template<typename ReturnType, ReturnType Fn()>
class Proxy
{
    void run()
    {
        ReturnType ret = Fn();
        // ... do something ...
    }
};

// and a functions
int fn1() { return 5; }
float fn2() { return 5; }

Questo può essere un'istanza utilizzando:

Proxy<int, &fn1> p1;

Ma dichiarando esplicitamente il tipo di valore di ritorno sembra inutile. Quello che sto cercando di realizzare è qualcosa di simile:

 someProxyInstantation<&fn1> p1;
 someProxyInstantation<&fn2> p2;

Purtroppo, io non sono un C ++ aspettarsi e questo mi sembra un angolo nascosto del linguaggio (almeno per me).

Se solo potessi ottenere dal puntatore alla funzione al suo tipo - qualcosa di simile a:      std :: tr1 :: result_of <& Fn> :: tipo // Errore 1 Errore C2923: 'std :: tr1 :: result_of': 'fn1' non è un tipo di modello argomento valido per il parametro '_Fty'

l'errore ha un senso in quanto il parametro non è un "tipo" a tutti

C ++ 0x ha il decltype (& fn1), ma che è lontano anni.

Qualsiasi modo di fare questo in C ++ 03 (+ TR1)?

Restrizioni:  -. Non voglio passare il funtore, F1 e F2 deve rimanere funzioni globali che hanno un valore di ritorno (non può spostarlo parametro))

È stato utile?

Soluzione

Questo non è possibile in C ++ 03. Se si desidera passare un puntatore a funzione come un parametro non tipo, il compilatore deve conoscere il tipo di parametro. Quindi, è necessario fornire i pezzi mancanti (in questo caso, il tipo di ritorno). Si può dare il proxy il puntatore a funzione come un valore in fase di esecuzione, e fornire con il tipo di esso come unico argomento. Poi si potrebbe scrivere una funzione generatore per te che fa questo lavoro:

template<typename T>
Proxy<T> make_proxy(T t) { return Proxy<T>(t); }

Purtroppo, in corrente C ++, si devono ancora dare il tipo al fine di assegnare a una variabile automatica:

Proxy<int(*)()> p = make_proxy(&fn1);

Non è possibile utilizzare ancora auto p = make_proxy(&fn1);. Si noti che se si desidera utilizzare un tipo di funzione sul lato sinistro, è necessario modificare la funzione del generatore di fornire non un tipo di puntatore a funzione:

template<typename T>
Proxy<typename boost::remove_pointer<T>::type> make_proxy(T t) { 
    return Proxy<typename boost::remove_pointer<T>::type>(t); 
}

Ora si può fare

Proxy<int()> p = make_proxy(&fn1);

con il proxy, è ora possibile solo fare

doSomething(make_proxy(&fn1));

E se doSomething è basato su modelli o altrimenti polimorfa, non richiedono di conoscere l'esatto tipo di funzione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top