Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Declare "container" object from templated template class and variadic templates

I need to declare a class which could store different kind of containers. i.e. It would be nice if it could handle std::bitset and std::array. However, these two classes need a different of template arguments... Is it possible (and possibly, how) to use templated template classes and variadic templates to declare this kind of class?

Example (but wrong):

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

The compiler complains that N/2 is not a type. Obviously, for both std::array and std::bitset I need the size to be the last template parameter... Is it possible to code this crazyness?

Thank you!

EDIT: As far as I am concerned, the main problem is that variadic templates can only be expanded on the right, therefore the variadic parameter must be the last one. Anyone know if there are any plans to allow the following syntax in C++17?

template<typename... Args, typename T>
struct A
{};
like image 907
dodomorandi Avatar asked Apr 03 '15 09:04

dodomorandi


2 Answers

Anton's answer can be made somewhat less container-specific by using template template parameters for the speciliasations of 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;
}
like image 67
Walter Avatar answered Nov 18 '22 08:11

Walter


Maybe something like this:

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;
}
like image 44
Anton Savin Avatar answered Nov 18 '22 07:11

Anton Savin