17

リスト内の最大数を決定するためにそれ自体を呼び出す可変個引数テンプレート関数があります (テンプレート化された引数によって構成されます)。パラメータ パックが空の場合に特殊化しようとしているので、リストの先頭にある番号を返すことができますが、その方法がわかりません。可変個引数テンプレートとテンプレートの特殊化に慣れてきたばかりですが、これまでのところ次のとおりです。

#include <string>
#include <iostream>

using namespace std;

template <int N, int... N2>
int tmax() {
    return N > tmax<N2...>() ? N : tmax<N2...>();
}

template <int N>
int tmax() {
    return N;
}

int main() {
    cout << tmax<32, 43, 54, 12, 23, 34>();
}

ただし、これにより次のエラーが発生します。

test.cpp: In function ‘int tmax() [with int N = 34, int ...N2 = {}]’:
test.cpp:9:45:   instantiated from ‘int tmax() [with int N = 23, int ...N2 = {34}]’
test.cpp:9:45:   instantiated from ‘int tmax() [with int N = 12, int ...N2 = {23, 34}]’
test.cpp:9:45:   instantiated from ‘int tmax() [with int N = 54, int ...N2 = {12, 23, 34}]’
test.cpp:9:45:   instantiated from ‘int tmax() [with int N = 43, int ...N2 = {54, 12, 23, 34}]’
test.cpp:9:45:   instantiated from ‘int tmax() [with int N = 32, int ...N2 = {43, 54, 12, 23, 34}]’
test.cpp:18:39:   instantiated from here
test.cpp:9:45: error: no matching function for call to ‘tmax()’
test.cpp:9:45: error: no matching function for call to ‘tmax()’

私もこれを試してみましたが、それが機能するかどうかを確認するためです (ただし、0 未満の数値を返すことができないように、リストに数値 0 をランダムに導入します)。

template <int N, int... N2>
int tmax() {
    return N > tmax<N2...>() ? N : tmax<N2...>();
}

template <>
int tmax<>() {
    return 0;
}

ただし、上記のエラーに加えて、次のエラーが発生します。

error: template-id ‘tmax<>’ for ‘int tmax()’ does not match any template declaration

では、これを機能させるにはどうすればよいですか?

-std=c++0xフラグ付きで g++ 4.5.2 を使用しています。

4

3 に答える 3

27

clangの使用に 2 つの誤りがあります。

  1. 単一の int を取るオーバーロードを最初に置きます。

  2. 長さ 1 のリストを明確にします。可変長リストはサイズが 0 になる可能性があることを思い出してください。

これは私にとって正しくコンパイルされ、実行されます:

#include <iostream>

using namespace std;

template <int N>
int tmax() {
    return N;
}

template <int N, int N1, int... N2>
int tmax() {
    return N > tmax<N1, N2...>() ? N : tmax<N1, N2...>();
}

int main() {
    cout << tmax<32, 43, 54, 12, 23, 34>();
}

54

于 2011-06-22T01:19:38.810 に答える
5

個人的には、この種の関数ではなく静的クラス メンバーを使用することをお勧めします。

template <int... N> struct max;
template <int N, int... M> struct max<N, M...> {
  static const int value = max<N, max<M...>::value>::value;
};    
template <int N, int M> struct max<N, M> {
  static const int value = N > M ? N : M;
};

int main()
{
  return max<1,2,3>::value;
}

更新: ildjarn の提案を使用して、冗長性の低いバージョンを次に示します。

#include <type_traits>
template <int... N> struct max;
template <int N, int... M> struct max<N, M...>
  : std::integral_constant<int, max<N, max<M...>::value>::value> { };
template <int N, int M> struct max<N, M>
  : std::integral_constant<int, (N > M ? N : M)> { };
于 2011-06-22T01:16:39.217 に答える
0

関数を部分的に特殊化することはできないため、関数をラップする必要があります。

template<int Head, int... Tail>
struct Tmax{
  static int do(){
    return Head > Tmax<Tail...>::do() ? Head : Tmax<Tail...>::do();
  }
};

template<int N>
struct Tmax<N>{
  static int do(){
    return N;
  }
};

template<int... Numbers>
int tmax(){
  return Tmax<Numbers...>::do();
}
于 2011-06-22T01:08:47.547 に答える