我应该怎么做,而不是部分特化函数模板

What should I do instead of partial specialization of function templates?

本文关键字:函数模板 我应该      更新时间:2023-10-16

我想写以下内容:

template <typename S, typename T> void foo() {
    /* code for the general case */
}
template <typename T> void foo<MySType,T>() {
    /* partially specialized code - for any kind of T, but when S is MySType */
}

,或者在其他情况下:

template <typename S, typename T> void bar(const S& a, const T& b) {
    /* code for the general case */
}
template <typename T> void bar<MySType,T>(const MySType& a, const T& b) {
    /* partially specialized code - for any kind of T, but when S is MySType */
}

c++(11)不允许我这样做。

现在,我读了这个问题和答案;让我们假设我接受了为什么我们没有部分模板专门化的解释(或者只是假设我生活在现实中并且实际上想要编写代码)。那么,该怎么做呢? 该怎么做呢?

我真的不想把这些函数包装在一个类中,除非这是我最后的选择。

超载!重载在各方面都优于专门化。重载解析的一部分是选择最专门化的重载。只要将"专门化"声明为重载,如果部分专门化会重载,它就会工作。

但是,要避免显式的模板参数。您可以使用标记调度。
template< typename t >
struct tag {};
template <typename S, typename T> foo( tag<S>, tag<T> ) {
    /* code for the general case */
}
template <typename T> foo( tag<MyType>, tag<T> ) {
    /* partially specialized code - for any kind of T, but when S is MyType */
}

由于标记为空并按值传递,因此编译器可以消除它们对函数调用开销的贡献。

另一个选择是使用helper类模板,其中可以执行部分专门化,并使用不需要部分专门化的包装器函数隐藏它:

#include <iostream>
template<typename S, typename T>
struct foo_helper {
    void foo() {
        std::cout << "general func" << std::endl;        
    }
};
struct MyType {};
template <typename T>
struct foo_helper <MyType,T> {
    void foo() {   
        std::cout << "partially specialized code - for any kind of T, but when S is MyType" << std::endl;
    }
};
template<typename S, typename T>
void foo() {
    foo_helper<S, T>().foo();
}
int main () {
    foo<int, int>();
    foo<int, double>();
    foo<MyType, long>();
}

可以局部专门化一个helper结构:

#include <iostream>
namespace Detail {
    template <typename S, typename T>
    struct Foo {
        static void apply() {
            std::cout << "general casen";
        }
    };
    template <typename T>
    struct Foo<int, T> {
        static void apply() {
            std::cout << "specialized coden";
        }
    };
}
template <typename S, typename T>
void foo() {
    Detail::Foo<S, T>::apply();
}
int main()
{
    foo<double, double>();
    foo<int, double>();
    return 0;
}