You can "extract" the template parameters you want to specialize on, make them the template parameters of some structure, and write the function with the remaining template parameters as static member function:
template<bool IsVector = true>
struct Bar {
template<typename In>
static auto foo(In input) {
return input[0];
}
};
template<>
struct Bar<false> {
template<typename In>
static auto foo(In input) {
return input;
}
};
Live example.
Obviously this results in a change at the call site, which you can "catch" using a free function that is calling the appropriate function:
template<typename In, bool IsVector>
auto real_foo(In input) {
return Bar<IsVector>::foo(input);
}
The structures (Bar
) are then normally put inside an "helper" namespace.
Another possibility is to use tags and overload resolution:
template<typename In>
auto foo(In input, std::true_type) {
return input[0];
}
template<typename In>
auto foo(In input, std::false_type) {
return input;
}
template<bool IsVector, typename In>
auto foo(In input) {
using tag = typename conditional<IsVector, true_type, false_type>::type;
return foo(input, tag{});
}
Live example.
This uses std::conditional
with std::true_type
and std::false_type
as different types to allow overload resolution to find the appropriate foo
function.