2014-10-17 63 views
10

假设我有一个具有以下特征的类:如何使用可变参数模板来enable_if类?

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: error: parameter pack ‘Args’ must be at the end of the template parameter list class A;

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

How to use std::enable_if with variadic template

但是,尽管名称,这个问题和它的答案是没有太大的帮助。如果有人可以提供或链接指导如何接近这一点,以及为什么会被赞赏。

回答

8

首先,你想在写多个定义是什么的类模板。这是不允许的,因为它违反了一个定义规则。如果你想通过班级进行条件启用,你需要专业。此外,编译器错误消息已经告诉您,您不能在参数列表中间添加可变参数包。

一种方式做到这一点是:

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,但如果你想添加更多专业化每个取决于几个它可能不是有用conditons。

+0

我试图声明'A a;',但编译器一直告诉我:“未定义模板的隐式实例'细节:: A_impl '如果你能解释这一点,我会很感激的。(对不起,我还在学习这些东西)。 – astroboylrx 2016-12-20 19:39:12

+0

@astroboylrx为了这个工作,第一个输入'A'的模板参数列表中需要有一个'value'成员,因为'enable_if'中的检查依赖于它,您已经使用'float'而不是'value'成员,'enable_if'中的检查是无效的,所以'A_impl'的主模板(它没有实现,只声明)被选中,你会得到错误。 – jrok 2016-12-21 18:31:48

+0

对不起,我迟到的回复。感谢您的解释。我现在看到它。 :-) – astroboylrx 2017-01-05 19:31:45

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

所以你必须在提供'Args'时手动提供'B' ... – Jarod42 2014-10-17 08:58:00

+3

我认为使用[这里的模板别名](http://coliru.stacked-crooked.com/a/524efebedc6a4d1c)是更接近OP的要求 – 2014-10-17 08:58:00

+0

是的,很简单,然后将其包装在别名中以使其更易于使用 – 2014-10-17 11:07:57

相关问题