问题
Considering class templates, it is possible to provide template specializations for certain types of groups using type traits and dummy enabler template parameters. I've already asked that earlier.
Now, I need the same thing for function templates: I.e., I have a template function and want a specialization for a group of types, for example, all types that are a subtype of a class X
. I can express this with type traits like this:
std::enable_if<std::is_base_of<X, T>::value>::type
I thought about doing it this way:
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
}
However, this does not work since partial specialization is not allowed for function templates. So how to do it then? Maybe a default parameter with the type trait as type? But how does the code look like then?
回答1:
The closest to what you're asking is enable_if
on the return type:
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();
However, dispatching to a helper function or class is likely to be more readable and efficient.
Helper function:
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>()); }
Helper class:
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(); }
回答2:
Overloads:
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>()); }
回答3:
Do the actual implementation (partial specializations etc..) in class templates and write a small wrapper template function that does nothing but call a static function in your class templates.
回答4:
Tried a few things and finally came up with the correct syntax myself - sorry for asking. I didn't know that enable_if has a second parameter. By using this parameter and a default value, it is possible.
Here is the answer
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";
}
来源:https://stackoverflow.com/questions/12250026/function-templates-different-specializations-with-type-traits