如何使用可变参数模板参数enable_if一个类?

时间:2014-10-17 08:39:34

标签: c++ templates

假设我有一个具有以下签名的类:

template <typename T, typename... Args>
class A;

但是这个类的行为应该取决于其他一些参数,假设它是T::value的值:

template <typename T, typename... Args, typename Enable>
class A;

template <typename T, typename... Args, typename = typename std::enable_if<T::value>::type>
class A
{
  // do something
};

template <typename T, typename... Args, typename = typename std::enable_if<!T::value>::type>
class A
{
  // do something else
};

int main() { return 0; }

但是,该程序会出现以下错误:

  

prog.cpp:6:11:错误:参数包'Args'必须在结尾处   模板参数列表        A级;

我一直在努力寻找有关使用enable_if来选择具有可变参数模板的类的良好信息来源。我能找到的唯一问题就是这个问题:

How to use std::enable_if with variadic template

但是尽管有这个名字,这个问题及其答案并没有太大帮助。如果有人可以提供或链接有关如何处理此问题的指南以及为什么会对此表示赞赏。

2 个答案:

答案 0 :(得分:9)

看起来你不需要启用/禁用该类,只需要部分专业化:

template <typename T, bool B = T::value, typename... Args>
  class A;

template <typename T, typename... Args>
  class A<T, true, Args...>;

template <typename T, typename... Args>
  class A<T, false, Args...>;

答案 1 :(得分:9)

首先,您正在尝试编写类模板的多个定义。这是不允许的,因为它违反了一个定义规则。如果要对类进行条件启用,则需要特化。此外,编译器错误消息已经告诉您,您不能在参数列表的中间有一个可变参数包。

一种方法是:

namespace detail {

template<typename T, typename Enable, typename... Args>
class A_impl;

template<typename T, typename... Args>
class A_impl<T, typename std::enable_if<T::value>::type, Args...> {
    // code here
};

template<typename T, typename... Args>
class A_impl<T, typename std::enable_if<!T::value>::type, Args...> {
    // code here
};
}

template<typename T, typename...Args>
class A : public detail::A_impl<T, void, Args...> {};

Jonathan's way如果条件实际上是bool也非常好,但如果您希望添加更多依赖于几个条件的特化,则它可能没有用。