Domanda

Qual è la ragione per la seconda parentesi <> nel seguente modello di funzione:

template<> void doh::operator()<>(int i)

Questo è venuto in domanda SO in cui è stato suggerito che ci sono staffe dispersi dopo operator(), tuttavia, non sono riuscito a trovare la spiegazione.

ho capito il significato, se si trattava di un tipo di specializzazione (pieno di specializzazione) del modulo:

template< typename A > struct AA {};
template<> struct AA<int> {};         // hope this is correct, specialize for int

Tuttavia, per i modelli di funzione:

template< typename A > void f( A );
template< typename A > void f( A* ); // overload of the above for pointers
template<> void f<int>(int);         // full specialization for int

Da dove viene questo rientrano in questa scenarion:?

template<> void doh::operator()<>(bool b) {}

il codice di esempio che sembra funzionare e non dà alcun avviso / errore (3.3.3 gcc usato):

#include <iostream>
using namespace std;

struct doh
{
    void operator()(bool b)
    {
        cout << "operator()(bool b)" << endl;
    }

    template< typename T > void operator()(T t)
    {
        cout << "template <typename T> void operator()(T t)" << endl;
    }
};
// note can't specialize inline, have to declare outside of the class body
template<> void doh::operator()(int i)
{
    cout << "template <> void operator()(int i)" << endl;
}
template<> void doh::operator()(bool b)
{
    cout << "template <> void operator()(bool b)" << endl;
}

int main()
{
    doh d;
    int i;
    bool b;
    d(b);
    d(i);
}

Output:

operator()(bool b)
template <> void operator()(int i)
È stato utile?

Soluzione

Ho guardato in su, e ha scoperto che è specificato da 14.5.2 / 2:

  

Una classe locale non deve avere modelli di membro. Regole di controllo dell'accesso (clausola 11) si applicano ai nomi dei modelli utente. Un distruttore non deve essere un modello di membro. Un normale (non-template) funzione membro con un dato nome e il tipo e modello di funzione membro dello stesso nome, che potrebbe essere utilizzato per generare una specializzazione dello stesso tipo, può sia essere dichiarato in una classe. Quando entrambi esistono, un uso di tale nome e il tipo si riferisce al membro non modello di meno che un elenco di modelli argomento esplicito viene fornito.

E fornisce un esempio:

template <class T> struct A {
    void f(int);
    template <class T2> void f(T2);
};

template <> void A<int>::f(int) { } // non-template member
template <> template <> void A<int>::f<>(int) { } // template member

int main()
{
    A<char> ac;
    ac.f(1); //non-template
    ac.f(’c’); //template
    ac.f<>(1); //template
}

Si noti che in termini standard, specialization si riferisce alla funzione che si scrive con una specializzazione esplicita e per la funzione generata utilizzando esemplificazione, in questo caso abbiamo a che fare con una specializzazione generato. specialization non si riferisce solo alle funzioni create utilizzando esplicitamente specializzata un modello, per il quale è spesso utilizzato solo.

Conclusione: GCC sbaglia. Comeau, con il quale ho anche provato il codice, ottiene di destra ed emette una diagnosi:

  

"ComeauTest.c", linea 16: errore: "void doh::operator()(bool)" non è un'entità che             può essere esplicitamente specializzata     template<> void doh::operator()(bool i)

Si noti che non si lamenta la specializzazione del modello per int (solo per bool), dal momento che non si riferisce allo stesso nome e Tipo: il tipo di funzione che la specializzazione avrebbe avere è void(int), che è distinta dalla funzione tipo di funzione membro non-template, che è void(bool).

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