函数模板:使用类型特征进行不同的特化

8
考虑到类模板,可以使用类型特征和虚拟启用器模板参数为某些类型组提供模板特化。我之前已经问过了
现在,我需要同样的内容应用于函数模板:也就是说,我有一个模板函数,并且想要针对一组类型进行特化,例如所有子类型为类X的类型。我可以使用类型特征来表达这个意思。
std::enable_if<std::is_base_of<X, T>::value>::type

我考虑用这种方式来做:

template <typename T, typename ENABLE = void>
void foo(){
    //Do something
}

template <typename T>
void foo<T,std::enable_if<std::is_base_of<A, T>::value>::type>(){
    //Do something different
}

然而,这并不起作用,因为函数模板不允许部分特化。那么该怎么做呢?也许可以使用带有类型特征的默认参数作为类型?但是代码看起来会是什么样子呢?

你实际上是用这个做什么的?更喜欢重载函数而不是专门化它们的模板。希望你打算使用它允许这样做。 - Seth Carnegie
4个回答

9

重载:

void foo_impl(T, std::false_type);

void foo_impl(T, std::true_type);

foo(T t) { foo_impl(t, std::is_base_of<A, T>()); }

4

你所需的最接近的功能是在返回类型上使用enable_if

template<typename T> typename std::enable_if<std::is_same<T, int>::value>::type foo();
template<typename T> typename std::enable_if<std::is_same<T, char>::value>::type foo();

然而,派发到一个辅助函数或类很可能更易读且更高效。

辅助函数:

template<typename T> void foo_helper(std::true_type);
template<typename T> void foo_helper(std::false_type);
template<typename T> void foo() { foo_helper(std::is_same<T, int>()); }

辅助类:

template<typename T, bool = std::is_same<T, int>::value> struct foo_helper {};
template<typename T> struct foo_helper<T, true> { static void foo(); };
template<typename T> struct foo_helper<T, false> { static void foo(); };
template<typename T> void foo() { foo_helper<T>::foo(); }

好的,通过使用返回类型,我甚至可以省略默认参数。 - gexicide
1
@gexicide 然而,你必须为每个函数定义进行特化,因此失去了像类模板那样拥有“捕获所有”定义的能力。 - Seth Carnegie

0

在类模板中进行实际实现(部分特化等),并编写一个小的包装器模板函数,仅调用您的类模板中的静态函数。


0
尝试了几种方法,最后我自己想出了正确的语法 - 对不起,我不知道 enable_if 还有第二个参数。通过使用这个参数和默认值是可能的。
这就是答案。
template<typename T>
void foo(typename std::enable_if<std::is_base_of<A, T>::value,int>::type ENABLER = 0){
    std::cout << "T is a subclass of A!";
}

template<typename T>
void foo(typename std::enable_if<!std::is_base_of<A, T>::value,int>::type ENABLER = 0){
    std::cout << "T is NOT a subclass of A";
}

再次,您失去了一般情况。 - Seth Carnegie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接