我之前问过this question a solution出现在哪里。就问题而言,解决方案很棒,但现在我对如何定义类的外部方法感到困惑,即我想在.inl
中定义方法文件。在这种情况下,语法是什么?
为了清楚起见,对于模板类,方法定义将是:
template <typename T>
struct Foo
{
Foo();
};
// C-tor definition
template <typename T>
Foo<T>::Foo()
{
}
如何使用enable_if
作为参数之一定义模板类的方法?
template <typename Policy, enable_if< is_base<BasePolicy, Policy>::value >::type >
struct Foo
{
Foo();
};
// C-tor definition -- ???
答案 0 :(得分:14)
从它的外观来看,你想要做的事情就是这样:
template <typename Policy,
typename = typename std::enable_if<std::is_base_of<BasePolicy, Policy>::value>::type >
struct Foo;
template <typename Policy>
struct Foo<Policy> {
Foo();
};
template <typename Policy>
Foo<Policy>::Foo() {
}
这偷偷地利用了几个地方的默认参数:不要混淆,隐含的void
坐在几个地方。
答案 1 :(得分:8)
以下是SFINAE如何实际使用部分专业化:
template<typename T, typename Sfinae = void>
struct Foo {
/* catch-all primary template */
/* or e.g. leave undefined if you don't need it */
};
template<typename T>
struct Foo<T, typename std::enable_if<std::is_base_of<BasePolicy, T>::value>::type> {
/* matches types derived from BasePolicy */
Foo();
};
然后可以通过以下方式笨拙地介绍该构造函数的定义:
template<typename T>
Foo<T, typename std::enable_if<std::is_base_of<BasePolicy, T>::value>::type>::Foo()
{
/* Phew, we're there */
}
如果你的编译器支持模板别名(它是一个C ++ 11特性),那么你可以减少很多冗长:
template<typename T>
using EnableIfPolicy = typename std::enable_if<std::is_base_of<BasePolicy, T>::value>::type;
// Somewhat nicer:
template<typename T>
struct Foo<T, EnableIfPolicy<T>> {
Foo();
};
template<typename T>
Foo<T, EnableIfPolicy<T>>::Foo() {}
注意:您的原始答案提到了Boost的实用程序,例如boost::enable_if_c
和boost::is_base_of
。如果您使用的是std::enable_if
和std::is_base_of
(来自C ++ 11),那么使用情况就像
typename boost::enable_if<boost::is_case_of<BasePolicy, T> >::type
其优点是可以摆脱一个::value
。