如何为模板化类型提供模板函数的专门化

How do I provide specialization of template function for a templated type?

本文关键字:函数 专门化 类型      更新时间:2023-10-16

我有一个模板函数,我想为它提供专门化,以便处理boost::optional<T>。然而,如果我想让我的专业化处理所有类型的boost::optional<T>,而不是像boost::optional<int>这样的特定类型,我似乎无法为这种场景找到合适的语法。

这里有一个可编译的例子:

#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() {}

不要专门化。请改为提供过载。

template <typename U>
void foo(const boost::optional<U>& t)
{
}

不能部分专用化模板函数。但你可以为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
}

否则你可以提供过载(可能更简单)

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>&) {}

关于过载方法的注意事项:

- `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.