5

Мне нужно объявить класс, который может хранить различные типы контейнеров. Т.е. было бы неплохо, если бы он мог обрабатывать std :: bitset и std :: array. Однако эти два класса нуждаются в разных аргументах шаблона ... Возможно ли (и, возможно, как) использовать шаблонные шаблонные классы и вариативные шаблоны для объявления этого класса?Объявить объект «контейнер» из шаблонного шаблона и вариативных шаблонов

Пример (но неправильно):

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

Компилятор жалуется, что N/2 не является типом. Очевидно, что для std :: array и std :: bitset мне нужен размер, который будет последним параметром шаблона ... Возможно ли кодировать эту сумасшедшую?

Спасибо!

EDIT: Насколько мне известно, основная проблема заключается в том, что вариационные шаблоны могут быть расширены только справа, поэтому переменный параметр должен быть последним. Кто-нибудь знает, есть ли планы разрешить следующий синтаксис в C++ 17?

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

, какой компилятор ? – Walter

+0

Он дает ошибку как с g ++, так и с clang (очевидно, с параметром -std = C++ 11/14) – dodomorandi

ответ

3

ответ Антона можно сделать несколько менее контейнер конкретных с использованием параметров шаблона шаблон для speciliasations из ResizedContainer:

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

Может быть что-то вроде этого:

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

Это очень хорошо. Во всяком случае, это довольно специфично для контейнера. Любые идеи, чтобы избежать специализации шаблонов и записать полный общий шаблонный класс? – dodomorandi

+1

@dodomorandi Думаю, вы не можете. Синтаксис C++ не позволяет этого. –

+0

@AntonSavin * Синтаксис C++ не позволяет этого. * Я подозреваю, что вы правы, но можете ли вы «доказать» это? – Walter

Смежные вопросы