目前,我正在尝试获取一些代码,以对不同的类型做出不同的 react 。这不是确切的代码,但是可以传达信息。

template<class A, class B>
struct alpha {
  enum { value = 0 };
};

template<class T, class... Args>
struct alpha<std::tuple<Args...>, T> {
  enum { value = 1 };
};

// This gets ignored
template<class T, class... Args>
struct alpha<std::tuple<Args..., std::vector<T> >, T> {
  enum { value = 2 };
};

// This gets ignored
template<class T, class... Args>
struct alpha<std::tuple<Args..., T>, T> {
  enum { value = 3 };
};

template<class T, class... Args>
struct alpha<T, std::tuple<Args...> > {
  enum { value = 4 };
};

template<class... LArgs, class... RArgs>
struct alpha<std::tuple<LArgs...>, std::tuple<RArgs...> > {
  enum { value = 5 };
};

int main(int argc, char* argv[]) {
  std::cout << alpha<std::tuple<int, double>, double>::value << std::endl; // prints 1
  return 0;
}

我已经尝试了超过此代码显示的范围,但是到目前为止,仍然没有任何效果,而且我遇到了在非命名空间范围内进行显式专门化的问题。作为引用,我正在研究gcc 4.6(oneiric服务器随附的gcc 4.6),我认为它具有完整的可变参数模板支持。我不在乎如果实现能够检测参数包的最后一个参数以及其他类型,它会变得多么丑陋。有什么建议么?

编辑:
我想根据答案分享我使用的解决方案(这是一个示例)。
template<typename T> struct tuple_last;

template<typename T, typename U, typename... Args>
struct tuple_last<std::tuple<T,U,Args...>> {
  typedef typename tuple_last<std::tuple<U,Args...>>::type type;
};

template<typename T>
struct tuple_last<std::tuple<T>> {
  typedef T type;
};

namespace details {
// default case:
template<class T, class U>
struct alpha_impl {
enum { value = 1 };
};

template<class T>
struct alpha_impl<T, T> {
enum { value = 101 };
};

template<class T>
struct alpha_impl<T, std::vector<T>> {
enum { value = 102 };
};

// and so on.
}

template<class T, class... Args>
struct alpha<std::tuple<Args...>, T>
  : details::alpha_impl<T, tuple_last<std::tuple<Args...>>;

最佳答案

如果使用clang进行编译,它将有助于报告(2)和(3)不可用。您希望选择的(3)警告如下:

为什么Args不可推论? C++ 0x FDIS在§14.8.2.5/9中声明:

在您的专业领域中,std::tuple<Args..., T>类型是根据模板参数ArgsT指定的类型。它包含一个包扩展(Args...),但该包扩展不是最后一个模板参数(T是最后一个模板参数)。因此,tuple的整个模板参数列表(<Args..., T>的整体)是一个非推论上下文。std::tuple的参数列表是Args出现在模板专门化参数列表中的唯一位置。由于无法从此处推导它,因此根本无法推导,并且永远不会使用特化。
Matthieu M. provides a clever workaround in his answer

10-07 19:57
查看更多