我正在使用Tensor的模板化表示来实现外部产品。
张量的基本原型如下:
template <int N>
struct Tensor
{
Tensor<N - 1> x;
Tensor<N - 1> y;
Tensor<N - 1> z;
};
将Tensor<1>
专门化为降级为简单向量。我的Outer
函数定义为:
template <int N, int M>
Tensor<N + M> Outer(const Tensor<N> &lhs, const Tensor<M> &rhs)
{
Tensor<N + M> result;
result.x = Outer(lhs.x, rhs);
result.y = Outer(lhs.y, rhs);
result.z = Outer(lhs.z, rhs);
return result;
}
template <int N>
Tensor<N + 1> Outer(const Tensor<N> &lhs, const Tensor<1> &rhs)
{
Tensor<N + 1> result;
result.x = Outer(lhs.x, rhs);
result.y = Outer(lhs.y, rhs);
result.z = Outer(lhs.z, rhs);
return result;
}
template <>
Tensor<2> Outer(const Tensor<1> &lhs, const Tensor<1> &rhs)
{
Tensor<2> result;
result.x.x = lhs.x * rhs.x;
result.x.y = lhs.x * rhs.y;
result.x.z = lhs.x * rhs.z;
// and so on
return result;
}
订单A
的张量N
和订单B
的张量M
的外积只是A
每个元素的外积使用B
张量。任何张量为N
且张量为1
的张量的外积也是类似的。
基本案例只是两个1
张量(向量)的外积。除了,如上所述,我在MSVC中收到C1202
错误:
错误C1202:递归类型或函数依赖关系上下文过于复杂
在我对外部产品的定义中,我做错了什么?
答案 0 :(得分:3)
这对我来说很干净:
template<int N>
struct Tensor
{
Tensor<N - 1> x;
Tensor<N - 1> y;
Tensor<N - 1> z;
Tensor() { }
Tensor(const Tensor<N-1>& X, const Tensor<N-1>& Y, const Tensor<N-1>& Z)
: x(X), y(Y), z(Z)
{ }
};
template<>
struct Tensor<1>
{
double x;
double y;
double z;
Tensor() : x(), y(), z() { }
Tensor(double x, double y, double z) : x(x), y(y), z(z)
{ }
};
template<int N, int M>
Tensor<N + M> Outer(const Tensor<N>& lhs, const Tensor<M>& rhs)
{
Tensor<N + M> result;
result.x = Outer(lhs.x, rhs);
result.y = Outer(lhs.y, rhs);
result.z = Outer(lhs.z, rhs);
return result;
}
template<int N>
Tensor<N + 1> Outer(const Tensor<N>& lhs, const Tensor<1>& rhs)
{
Tensor<N + 1> result;
result.x = Outer(lhs.x, rhs);
result.y = Outer(lhs.y, rhs);
result.z = Outer(lhs.z, rhs);
return result;
}
template<int N>
Tensor<N + 1> Outer(const Tensor<1>& lhs, const Tensor<N>& rhs)
{
return Outer(rhs, lhs);
}
Tensor<2> Outer(const Tensor<1>& lhs, const Tensor<1>& rhs)
{
Tensor<2> result;
result.x.x = lhs.x * rhs.x;
result.x.y = lhs.x * rhs.y;
result.x.z = lhs.x * rhs.z;
result.y.x = lhs.y * rhs.x;
result.y.y = lhs.y * rhs.y;
result.y.z = lhs.y * rhs.z;
result.z.x = lhs.z * rhs.x;
result.z.y = lhs.z * rhs.y;
result.z.z = lhs.z * rhs.z;
return result;
}
int main()
{
Tensor<4> a;
Tensor<4> b;
Outer(a, b);
}
值得注意的变化是:
Tensor<1>
重载之前定义Outer
专精。Tensor<1>
专精化需要默认构建,因为Tensor<2>
将尝试默认构建其x
,y
和z
数据成员template<int N> Tensor<N + 1> Outer(const Tensor<1> &lhs, const Tensor<N> &rhs)
对称需要template<int N> Tensor<N + 1> Outer(const Tensor<N> &lhs, const Tensor<1> &rhs)
重载,或者您需要为double
添加lhs
的重载。template<>
重载中移除Tensor<2> Outer(const Tensor<1> &lhs, const Tensor<1> &rhs)
- 我们重载,而非专业化。