2012-11-22 33 views
5

E 'implementato già, perché questo non viene compilato: (usando GCC 4.7.2)variadic modello di specializzazione in C++ 11

template <typename... Ts> 
struct Foo { 
    int foo() { 
     return 0; 
    } 
}; 

template <> 
struct Foo<int x, int y> { 
    int foo() { 
     return x * y; 
    } 
}; 

int main() 
{ 
    Foo<2, 3> x; 
    cout << x.foo() << endl; //should print 6 
} 
+0

Se non si compila, che cosa è il compilatore lamenta? –

+0

I modelli Variadic sono stati implementati da molto tempo in gcc. Se si desidera controllare il supporto delle funzionalità: http://gcc.gnu.org/projects/cxx0x.html –

risposta

10

si stanno facendo un paio di errori. Il modello primario prevede tipi, non costanti integrali . Prova anche a creare un'istanza del modello con le costanti integrali , ma la specializzazione parziale utilizza i tipi.

Questo è più vicino:

#include <iostream> 

template <int... Ts> 
struct Foo { 
    int foo() { 
     return 0; 
    } 
}; 

template <> 
struct Foo<3, 2> { 
    const int x = 3; 
    const int y = 2; 

    int foo() { 
    return x * y; 
    } 
}; 

int main() 
{ 
    Foo<2, 3> x; 
    std::cout << x.foo() << std::endl; //should print 6 
} 

Ma questo non è proprio quello che vogliamo, giusto? Ed è anche maldestro.

#include <iostream> 

template<typename Acc, typename... Rest> 
struct accum_help; // primary 

template<typename Acc, typename F, typename... Rest> 
struct accum_help<Acc, F, Rest...> { 
    typedef typename accum_help< 
    std::integral_constant<typename Acc::value_type, 
          Acc::value * F::value>, Rest... 
    >::type type; 
}; 

template<typename Acc> 
struct accum_help<Acc> { 
    typedef Acc type; 
}; 

// peek into the first argument to avoid summing empty sequences and 
// get the right type 
template<typename X, typename... Integrals> 
struct accum { 
    typedef typename accum_help< 
    std::integral_constant<typename X::value_type, 1>, X, Integrals... 
    >::type type; 
}; 

int main() 
{ 

    std::cout << accum< std::integral_constant<int, 2>, std::integral_constant<int, 3> >::type::value << std::endl; //should print 6 
} 

Una variante più semplice la gestione solo int:

template <int...> 
struct accum2_help; 

template <int Acc, int X, int... Rest> 
struct accum2_help<Acc, X, Rest...> { 
    static const int value = accum2_help< Acc * X, Rest...>::value; 
}; 

template <int Acc> 
struct accum2_help<Acc> { 
    static const int value = Acc; 
}; 

// again don't accept empty packs 
template <int T, int... Ts> 
struct accum2 { 
    static const int value = accum2_help<1, T, Ts...>::value; 
}; 
+0

Quindi, come fare questo: 1. Dichiarare la '' versione di 'Foo' e istanziarla con le costanti' <2, 3> '? – Cartesius00

+0

'Foo <2, 3> x'? Non dovrebbe essere 'Foo <3, 2> x'? – Nawaz

+0

@Martin Se si desidera poter usare 'Foo' come' Foo <2, 3> ', allora sembra che il modello primario che si desidera sia qualcosa come' modello struct Foo; '. –

Problemi correlati