2014-10-22 14 views
12

Supponiamo che io ho alcune classi template definiti come segueEspansione di un parametro di pacchetto di template <class> classi

template<template<class>class...> 
struct my_class; 

template<class> 
struct define_template{ 
    template<class> 
    class type; 
}; 

ho bisogno di definire un modello di alias che sostituisce define_template :: tipo in my_class così per tre classi che potrei fare questo

template<class A, class B, class C> 
using my_alias = my_class< define_template<A>::template type, 
          define_template<B>::template type, 
          define_template<C>::template type>; 

non riesco a capire la sintassi di fare questo per un modello variadic idealmente qualcosa di simile

template<class... T> 
using new_class = my_class<define_template<T>::template type...>; 

che mi dà un errore "parametro non pacchi ampliato con '...'

Qualcuno sa lo SYNAX corretta?

Dai commenti sotto compila in clang, sto usando gcc 4.8.2 tramite Cygwin.

+3

nessun errore in [clang] (http://coliru.stacked-crooked.com/a/88552814d04f29fe) –

+0

* vc2 013 * [conforme anche a questo codice] (http://rextester.com/EVN44627). Sembra che sia un bug in * g ++ *. – Constructor

risposta

1

Sto assumendo si tratta di un bug in gcc così ho fatto una soluzione per ora

// partially specializes a template 
template<template<class, class>class TT, class T> 
struct TemplateBind{ 
    template<class S> 
    using type = TT<T, S>; 
}; 


// the workaround 
template<template<template<class>class...>class A, 
     template<class, class>class B, 
     template<class>class... C> 
class workaround { 
    template<class D, class... E> 
    static auto get_type(D, E...) 
    -> typename workaround<A, B, C..., TemplateBind<B, D>::template type>::template type<E...>; 

    static auto get_type() 
    ->A<C...>; 

public: 
    template<class... T> 
    using type = decltype(get_type(std::declval<T>()...)); 

}; 

// convinience alias 
template<template<template<class>class...>class OriginalTemplate, 
     template<class, class>class Substitution, 
     class... Types> 
using InstatiateVariadicTemplateTemplate = typename workaround<OriginalTemplate, Substitution>::template type<Types...>; 

Poi possiamo definire un wrapper per define_template

// wrapper alias gets define_template in the right form 
template<class A, class B> 
using my_wrapper = typename define_template<A>::template type<B>; 

e istanziare come segue

template<class... T> 
using my_alias = InstatiateVariadicTemplateTemplate<my_class, my_wrapper, T...>;