Ann*_*ova 5 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;
}
Run Code Online (Sandbox Code Playgroud)
如果我使用这种专业化T scalar_product<T, 0>(...),我会收到错误" 'scalar_product':非法使用显式模板参数 ".但是,如果我像这个T scalar_product(...)编译器报告一样删除它,递归将是无限的(因为没有专业化,据我所知).
这里有很多这类问题,但我找不到有用的答案.如何在不使用类的情况下专门化这个功能?先谢谢你了!
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];
}
};
Run Code Online (Sandbox Code Playgroud)
或者,您可以使用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];
}
Run Code Online (Sandbox Code Playgroud)
请注意,我在这两个函数中使用了 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));
}
Run Code Online (Sandbox Code Playgroud)
请注意,如果没有(Size==0) ? Size : Size - 1,编译器将为所有 int 值创建一个函数,否则就会失败。