10

テンプレートの引数を繰り返さずに (マクロを使用せずに)、テンプレートの基本クラスからコンストラクターを継承するにはどうすればよいですか?

たとえば、これは機能しません (GCC 4.8 を使用):

template <typename T>
struct base {};

template <typename U>
struct derived : base<U> {
    using base::base;
};

基本クラスのテンプレート引数を繰り返すと機能します。

template <typename T>
struct base {};

template <typename U>
struct derived : base<U> {
    using base<U>::base;
};

問題は、「U」が非常に複雑なものである可能性があり、それが煩わしく、エラーが繰り返されやすいことです。たとえば、これは私の元の動機付けの例の 1 つです。

#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 ;
};

私はマクロを使用してこれを回避しました:

#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

これにアプローチするより良い方法はありますか?私が見逃しているいくつかの構文トリックはありますか? =)

4

4 に答える 4

3

完全ではありませんが、型を生成するクラスを作成できます。

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 ;
};
于 2013-04-04T02:59:37.590 に答える
2

簡単:

template <typename U, typename thebase=base<U>>
struct derived : thebase {
    using thebase::thebase;
};

欠点は、テンプレートの外部インターフェイスが 2 つのテンプレート引数を持つように変更されることです。次のように解決できます。

template <typename U, typename thebase=base<U>>
struct derived_impl : thebase {
    using thebase::thebase;
};
template<typename U>
using derived = derived_impl<U>;
于 2016-04-14T13:09:50.307 に答える
2

ダニエル・フレイのソリューションを強調するために、彼は完全な答えを出すことを気にしませんでした.宣言を使用したテンプレート(別名テンプレートtypedef)が道です。

template <typename T>
using unique_list_base =
    multi_index_container <
        T,
        indexed_by <
            sequenced<tag<as_list_tag>>,
            ordered_unique<tag<as_set_tag>, identity<T>>
        >
    >;

template <typename T>
struct unique_list : unique_list_base<T> {
    using unique_list_base<T>::multi_index_container;
    using as_list = as_list_tag;
    using as_set  = as_set_tag ;
};

このようにして、C++03イディオムstructで広く使用されていた および関連するすべてのボイラープレートを取り除くことができます。foobar<T>::type

于 2013-04-04T08:46:55.747 に答える