How do I inherit constructors from a template base class without repeating the template arguments (and without using macros):
For example, this does not work (using GCC 4.8):
template <typename T>
struct base {};
template <typename U>
struct derived : base<U> {
using base::base;
};
It does work if I repeat the template arguments of the base class:
template <typename T>
struct base {};
template <typename U>
struct derived : base<U> {
using base<U>::base;
};
The problem is that "U" might be something very complex and that is annoying and error prone to repeat. For example, here is one of my original motivating examples:
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/key_extractors.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/sequenced_index.hpp>
using namespace boost::multi_index;
struct as_list_tag {};
struct as_set_tag {};
template <typename T>
struct unique_list : multi_index_container <
T,
indexed_by <
sequenced<tag<as_list_tag>>,
ordered_unique<tag<as_set_tag>, identity<T>>
>
> {
using multi_index_container <
T,
indexed_by <
sequenced<tag<as_list_tag>>,
ordered_unique<tag<as_set_tag>, identity<T>>
>
>
::multi_index_container;
using as_list = as_list_tag;
using as_set = as_set_tag ;
};
I ended up working around this by using a macro:
#define MAKE_UNIQUE_LIST(template_params...)\
template <typename T>\
struct unique_list : multi_index_container template_params\
{\
using multi_index_container template_params ::multi_index_container;\
using as_list = as_list_tag;\
using as_set = as_set_tag ;\
};
MAKE_UNIQUE_LIST(<
T,
indexed_by <
sequenced<tag<as_list_tag>>,
ordered_unique<tag<as_set_tag>, identity<T>>
>
>)
#undef MAKE_UNIQUE_LIST
Is there a better way to approach this? Some syntax trick I am missing? =)
Easy:
template <typename U, typename thebase=base<U>>
struct derived : thebase {
using thebase::thebase;
};
The downside is that it changes the external interface of the template to have two template arguments. You can solve that like this:
template <typename U, typename thebase=base<U>>
struct derived_impl : thebase {
using thebase::thebase;
};
template<typename U>
using derived = derived_impl<U>;
It isn't perfect, but you could have a class that generates your type:
template <typename T>
struct unique_list_base {
typedef multi_index_container <
T,
indexed_by <
sequenced<tag<as_list_tag>>,
ordered_unique<tag<as_set_tag>, identity<T>>
>
> type;
};
template <typename T>
struct unique_list : unique_list_base<T>::type {
using unique_list_base<T>::type::multi_index_container;
using as_list = as_list_tag;
using as_set = as_set_tag ;
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With