0

テンプレートについて質問があり、それはコードにあります:

template<typename T>
struct foo {
  T t;
};

template<typename FooType>
struct bar {
  T t; //<- how to get T here (preferably without using typedef in foo)
};
4

3 に答える 3

5

以下は、一般的なテンプレート引数型エクストラクタです。

#include <tuple>

template <typename> struct tuplify;

template <template <typename...> class Tpl, typename ...Args>
struct tuplify<Tpl<Args...>>
{
    using type = std::tuple<Args...>;
};

template <typename T, unsigned int N>
using get_template_argument
    = typename std::tuple_element<N, typename tuplify<T>::type>::type;

使用法:

get_template_argument<std::vector<int>, 1> a;  // is a std::allocator<int>

またはあなたの場合:

get_template_argument<FooType, 0> t;
于 2013-06-08T16:15:52.410 に答える
1

あなたの質問を正しく理解していれば、次のようにテンプレートの特殊化を使用できます。foo<>クラス テンプレートが与えられた場合:

template<typename T>
struct foo {
  T t;
};

bar<>プライマリ テンプレートと対応する特殊化を次のように定義します。

template<typename FooType>
struct bar;

template<typename T>
struct bar<foo<T>> {
  T t; // T will be int if the template argument is foo<int>
};

bar型引数として のインスタンスを提供することによって常にインスタンス化することになっているという前提の下でfoo<>、プライマリ テンプレートを未定義のままにしておくことができます。

特殊化はfoo<T>パターンに一致するため、foo<>でインスタンス化された型が得られますT

簡単なプログラムでこのアプローチの有効性をテストする方法を次に示します。

#include <type_traits>

int main()
{
    bar<foo<int>> b;

    // This will not fire, proving T was correctly deduced to be int
    static_assert(std::is_same<decltype(b.t), int>::value, "!");
}

対応するライブの例を次に示します。

于 2013-06-08T15:53:47.293 に答える
1

に typedef を追加したくない、または追加できない場合はfoo、独立した「エクストラクタ」テンプレートを追加で作成できます。

template <typename T> struct ExtractT;
template <typename T> struct ExtractT<foo<T> > {
  typedef T type;
};

そしてそれを次のように使用します

template<typename FooType>
struct bar {
  typename ExtractT<FooType>::type t;
}; 

それをExtractTさらに一歩進めて、foo

template <typename T> struct ExtractT;
template <template <typename> class C, typename T> struct ExtractT<C<T> > {
  typedef T type;
};

BoostまたはC++ 11標準ライブラリから何かを再発明するまで、など.

于 2013-06-08T15:57:42.800 に答える