16

コンパイル時に可変個引数のテンプレート化されたクラスの N 番目のパラメーターを取得する最も簡単で一般的な方法は何だろうか(いくつかの最適化を行うために、戻り値はコンパイラーの static const でなければなりません)。これが私のテンプレート化されたクラスのフォームです:

template<unsigned int... T> MyClass
{
    // Compile-time function to get the N-th value of the variadic template ?
};

どうもありがとうございました。

編集: MyClass には 200 を超える関数が含まれるため、特殊化することはできません。しかし、MyClass 内で構造体または関数を特殊化できます。

編集:検証済みの回答から派生した最終的な解決策:

#include <iostream>

template<unsigned int... TN> class MyClass
{
    // Helper
    template<unsigned int index, unsigned int... remPack> struct getVal;
    template<unsigned int index, unsigned int In, unsigned int... remPack> struct getVal<index, In,remPack...>
    {
        static const unsigned int val = getVal<index-1, remPack...>::val;
    };
    template<unsigned int In, unsigned int...remPack> struct getVal<1,In,remPack...>
    {
        static const unsigned int val = In;
    };

    // Compile-time validation test
    public:
        template<unsigned int T> inline void f() {std::cout<<"Hello, my value is "<<T<<std::endl;}
        inline void ftest() {f<getVal<4,TN...>::val>();} // <- If this compile, all is OK at compile-time
};
int main()
{
    MyClass<10, 11, 12, 13, 14> x;
    x.ftest();
    return 0;
}
4

4 に答える 4

10

「誘導による設計」は次のようになります。

template<unsigned int N, unsigned int Head, unsigned int... Tail>
struct GetNthTemplateArgument : GetNthTemplateArgument<N-1,Tail...>
{
};


template<unsigned int Head, unsigned int... Tail>
struct GetNthTemplateArgument<0,Head,Tail...>
{
    static const unsigned int value = Head;
};

template<unsigned int... T> 
class MyClass
{
     static const unsigned int fifth = GetNthTemplateArgument<4,T...>::value;
};
于 2012-08-04T19:40:59.377 に答える
6

これを行う別の方法を次に示します。

template<unsigned int index, unsigned int In, unsigned int... remPack> struct getVal
{
    static const unsigned int val = getVal<index-1, remPack...>::val;
};
template<unsigned int In, unsigned int...remPack> struct getVal<0,In,remPack...>
{
    static const unsigned int val = In;
};

template<unsigned int... T> struct MyClass
{
    //go to any arg by : getVal<Some_Unsigned_Index, T...>::val;
};

テスト: http://liveworkspace.org/code/4a1a9ed4edcf931373e7ab0bf098c847

そして、「「T...」を固定長の引数リストに展開できない」ということで刺された場合http://ideone.com/YF4UJ

于 2012-08-04T19:56:45.777 に答える
5

あなたもできることはここにあります

template<int N, typename T, T ... Ts>
struct GetN {
  constexpr T values[sizeof...(Ts)] = { Ts... };
  static const T value = values[N];
};

template<int N, typename T, T ... Ts>
constexpt T GetN<N, T, Ts...>::values[sizeof...(Ts)];

次に、簡単に行うことができます

template<int N, unsigned int... T> struct MyClass {
  static const unsigned int value = GetN<N, unsigned int, T...>::value;
};
于 2012-08-05T15:45:46.700 に答える
3

さらに別の簡単な方法:

#include <array>

template<int... Args>
class Foo {
 public:
  static constexpr int Element(int index) {
    return std::array<int, sizeof...(Args)>{ Args... }[index];
  }

 int First = Element(0);
 int Second = Element(1);
};


int main() {
  return Foo<0, 1>::Element(0);  
}

// or just
int Nth = std::array<int, sizeof...(Args)>{ Args... }[N];

ところで、これは可変個引数テンプレートの N 番目の引数を抽出する一般的な方法です。

#include <tuple>

template<typename... Args>
class Foo {
 public:
  template <int N>
  using Nth = typename std::remove_reference<decltype(std::get<N>(std::declval<std::tuple<Args...>>()))>::type;
};


int main() {
  Foo<int, float>::Nth<1> val = 3.14159f;
  return 0; 
}
于 2013-12-05T17:26:23.837 に答える