2015-04-03 28 views
5

Devo dichiarare una classe in grado di memorizzare diversi tipi di contenitori. Sarebbe bello se potesse gestire std :: bitset e std :: array. Tuttavia, queste due classi richiedono un diverso argomento del template ... E 'possibile (e possibilmente, in che modo) usare classi template template e modelli variadic per dichiarare questo tipo di classe?Dichiarare oggetto "contenitore" da modelli template classe e modelli variadic

Esempio (ma sbagliato):

template<template <typename..., std::size_t> class Container, 
     std::size_t N, 
     typename... Args> 
class Base_Class 
{ 
    ... 
    Container<Args..., N/2> container; 
}; 

Il compilatore lamenta che N/2 non è un tipo. Ovviamente, sia per std :: array che per std :: bitset ho bisogno che la dimensione sia l'ultimo parametro del template ... È possibile codificare questa follia?

Grazie!

MODIFICA: Per quanto mi riguarda, il problema principale è che i modelli variadici possono essere espansi solo a destra, quindi il parametro variadic deve essere l'ultimo. Qualcuno sa se ci sono piani per consentire la seguente sintassi in C++ 17?

template<typename... Args, typename T> 
struct A 
{}; 
+0

quale compilatore ? – Walter

+0

Dà errore sia con g ++ che clang (ovviamente con -std = C++ 11/14 parametro) – dodomorandi

risposta

3

risposta di Anton può essere reso un po 'meno utilizzando i parametri del modello modello per le speciliasations di ResizedContainer specifici container:

namespace detail { 
    template<typename Container> 
    struct ResizedContainer; 

    template<template<typename,std::size_t> class Container, 
      typename T, std::size_t N> 
    struct ResizedContainer<Container<T,N>> { 
     using type = Container<T,N/2>; 
    }; 

    template<template<std::size_t> class Container, 
      std::size_t N> 
    struct ResizedContainer<Container<N>> { 
     using type = Container<N/2>; 
    }; 
} 

#include <array> 
#include <bitset> 

template<typename Container> 
class Base_Class { 
    typename detail::ResizedContainer<Container>::type container; 
}; 

int main() { 
    Base_Class<std::array<int,4>> a; 
    Base_Class<std::bitset<5>> b; 
} 
2

Forse qualcosa di simile:

namespace detail { 
    template<typename Container> 
    struct ResizedContainer; 

    template<typename T, size_t N> 
    struct ResizedContainer<std::array<T, N>> { 
     using type = std::array<T, N/2>; 
    }; 

    template<size_t N> 
    struct ResizedContainer<std::bitset<N>> { 
     using type = std::bitset<N/2>; 
    }; 
} 

template<typename Container> 
class Base_Class { 
    typename detail::ResizedContainer<Container>::type container; 
}; 

int main() { 
    Base_Class<std::array<int, 4>> a; 
    Base_Class<std::bitset<5>> b; 
} 
+0

Questo è abbastanza buono. Ad ogni modo, è piuttosto specifico per container. Qualche idea per evitare la specializzazione del modello e annotare una classe template generica completa? – dodomorandi

+1

@dodomorandi Penso che non puoi. La sintassi C++ non lo consente. –

+0

@AntonSavin * La sintassi del linguaggio C++ non lo consente. * Sospetto che tu abbia ragione, ma puoi provarlo? – Walter

Problemi correlati