Reputation: 6424
I have a template function that I'd like to provide a specialization for, in order to handle boost::optional<T>
. However, I can't seem to figure out the proper syntax for this scenario, if I want to allow my specialization to handle all types of boost::optional<T>
, instead of a specific one like boost::optional<int>
.
Here's a compilable example:
#include <boost/optional.hpp>
template <typename T>
void foo(const T& t)
{}
// This works.
template<>
void foo<int>(const int& t)
{}
// This works.
template<>
void foo<boost::optional<int>>(const boost::optional<int>& t)
{}
// What to do in this case??
// template <typename U>
// void foo<boost::optional<U>>(const boost::optional<U>& t)
// {}
int main() {}
Upvotes: 1
Views: 392
Reputation: 217275
You cannot partial specialize template function. But you can do it for class
namespace detail
{
template <typename T>
struct foo_impl
{
void operator () (const T&) const {};
}
template <>
struct foo_impl<int> // Full specialization for int
{
void operator () (int) const {};
}
template <>
struct foo_impl<boost::optional<int>> // Full specialization for boost::optional<int>
{
void operator () (const boost::optional<int>&) const {};
}
template <typename T>
struct foo_impl<boost::optional<T>> // Partial specialization for boost::optional<T>
{
void operator () (const boost::optional<T>&) const {};
}
}
template <typename T>
void foo(const T& t)
{
detail::foo_impl<T>{}(t); // Forward to correct struct
}
else you can provide overload (which may be simpler)
template <typename T>
void foo(const T&) {}
void foo(int) {}
void foo(const boost::optional<int>&) {}
template <typename T>
void foo(const boost::optional<T>&) {}
Note about the overload method:
- `foo(42)` and `foo<int>(42)` won't call the same function
- and similarly, with `boost::optional<int> opt_i;`,
`foo(opt_i)`, `foo<int>(opt_i)` and `foo<boost::optional<int>>(opt_i)`
will call 3 different functions.
Upvotes: 2
Reputation: 16737
Don't specialize. Provide an overload instead.
template <typename U>
void foo(const boost::optional<U>& t)
{
}
Upvotes: 5