10

テンプレート パラメーターとして渡される型のバリアントである内部型を作成するクラスを設計したいと考えています。次のような非機能的な例:

template <typename T>
class BaseClass
{
public:
    typedef T InternalType;
    std::vector<InternalType> storage;
};

template <typename Base>
class Injector
{
public:
    typedef std::pair<typename Base::InternalType, typename Base::InternalType> RefinedType;
    Base<RefinedType> refinedStorage;
};

typedef Injector<BaseClass<int> > InjectedInt; // Should store vector<pair<int, int> >

Baseは完全に指定された型であるためBase<RefinedType> refinedStorage;、コンパイルに失敗します。洗練された型は、ネストされたテンプレートのパラメーターとその基本型に基づく必要があるため、テンプレート テンプレート パラメーターを使用するだけでは機能しません。

テンプレート パラメーターの完全に指定された型と基本型の両方に基づいて型を作成するこのパターンを実装するにはどうすればよいですか?

編集:これは、変換のカスケードを実行する複数のインジェクタータイプを備えた、任意の深さのコンポジットにしたいと考えています。したがって、テンプレート テンプレート パラメーターとベース パラメーターの両方を渡すことはかなり扱いにくくなり (特に、コンポジットのベース ケースを処理する場合)、理想的な解決策はより直接的な構文を使用することです。

4

4 に答える 4

8

rebindテンプレートを導入できます:

template <typename From, typename To>
struct rebind_1st;

template <template <typename... > class Cls, typename A0, typename... Args, typename To>
struct rebind_1st<Cls<A0, Args...>, To> {
    using type = Cls<To, Args...>;
};

template <typename From, typename To>
using rebind_1st_t = typename rebind_1st<From, To>::type;

これにより、次のようにInjectorなります。

template <typename Base>
class Injector
{
public:
    typedef std::pair<typename Base::InternalType, 
                      typename Base::InternalType> RefinedType;
    rebind_1st_t<Base, RefinedType> refinedStorage;
};
于 2015-07-13T13:19:42.913 に答える
4

外部リバインダを提供できます:

template <class Bound, class U>
struct rebinder;

template <template <class> class Binder, class B, class U>
struct rebinder<Binder<B>, U>
{
  typedef Binder<U> type;
};

// Usage:

template <typename Base>
class Injector
{
public:
    typedef std::pair<typename Base::InternalType, typename Base::InternalType> RefinedType;
    typename rebinder<Base, RefinedType>::type refinedStorage;
};

【実例】

于 2015-07-13T13:18:15.880 に答える