假设我有一个具有以下签名的课程:
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
选择具有可变参数模板的类的良好信息来源。我能找到的唯一问题是这个:
如何将 std::enable_if 与可变参数模板一起使用
但是尽管有这个名字,这个问题及其答案并没有多大帮助。如果有人可以提供或链接有关如何处理此问题以及为什么这样做的指南,我们将不胜感激。
首先,您正在尝试编写类模板的多个定义。这是不允许的,因为它违反了“单一定义”规则。如果您想对类进行条件启用,则需要专业化。另外,编译器错误消息已经告诉您,参数列表中间不能有可变参数包。
一种方法是:
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...> {};
如果条件确实是 bool
,那么
Jonathan 的方式也完全没问题,但如果您希望添加更多专业化(每个专业化都依赖于多个条件),那么它可能就没用了。
看起来好像为了您的目的,您不需要启用/禁用该类,您只需要部分专业化:
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...>;