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的两个错误。

  1. 首先将重载放在一个 int 上。

  2. 使长度为 1 的列表变得明确。回想一下可变参数列表的大小可以为零,当它们这样做时,在我看来你有一个歧义。

这对我来说可以正确编译和运行:

#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 回答