模板函数专业化C ++

时间:2013-12-10 09:57:41

标签: c++ templates metaprogramming

我需要实现算法,使用模板递归计算两个向量的标量积。

有我的代码:

#include <iostream>
#include <vector>

template<typename T, int Size>
T scalar_product(const std::vector<T> &a, const std::vector<T> &b)
{
    return a[Size - 1]*b[Size - 1] + (scalar_product<T, Size - 1>(a, b));
}

template<typename T>
T scalar_product<T, 0>(const std::vector<T> &a, const std::vector<T> &b) // error!
{
    return a[0] * b[0];
}

int main()
{
    std::vector<int> a(3, 1);
    std::vector<int> b(3, 3);

    std::cout << scalar_product<int, 3>(a, b);
    return 0;
}

如果我使用此专业化T scalar_product<T, 0>(...),我会收到错误“'scalar_product':非法使用显式模板参数”。但是,如果我像这个T scalar_product(...)编译器报告一样删除它,递归将是无限的(因为没有专业化,据我所知)。

这里有很多这类问题,但我找不到有用的答案。如何在不使用类的情况下专门化这个功能?先谢谢你了!

1 个答案:

答案 0 :(得分:3)

no partial function template specialization。您可以使用functor,这可以是部分专业化的:

template<typename T, int Size>
struct myFunctor
{
    T scalar_product(const std::vector<T> &a, const std::vector<T> &b)
    {
        static_assert(Size > 0,"Size must be positive!")
        return a[Size - 1]*b[Size - 1] + (myFunctor<typename T, Size - 1>::scalar_product(a, b));
    }
};
template<typename T>
struct myFunctor<T,1>
{
    T scalar_product(const std::vector<T> &a, const std::vector<T> &b)
    {
        return a[0] * b[0];
    }
};

或者你可以使用std::enable_if来实现部分功能专业化。

template<typename T, int Size>
typename std::enable_if<(Size>1), T>::type scalar_product(const std::vector<T> &a, const std::vector<T> &b)
{
    return a[Size - 1]*b[Size - 1] + (scalar_product<T, Size - 1>(a, b));
}
template<typename T, int Size>
T scalar_product(const std::vector<T> &a, const std::vector<T> &b, typename std::enable_if<(Size == 1), void*>::type x = nullptr)
{
    return a[0] * b[0];
}

请注意,我在2个函数中使用了两种不同的方法来使用std :: enable_if,以表明两者都是可能的。两个函数都可以像第一个函数一样在返回类型上使用enable_if,并且它们都可以像第二个函数那样在参数上使用它们。如需更多阅读,请参阅SFINAE

或者作为第三个选项,你可以像这样处理函数内部的特化:

template<typename T, int Size>
T scalar_product(const std::vector<T> &a, const std::vector<T> &b)
{
    static_assert(Size > 0,"Size must be positive!")
    if (Size==1)
        return a[0] * b[0];
    return a[Size - 1]*b[Size - 1] + (scalar_product<T, (Size==1) ? Size : Size - 1>(a, b));
}

请注意,如果没有(Size==0) ? Size : Size - 1,编译器将为int的所有值创建一个函数,或者尝试死。