操作员与整数模板参数专业化过载
Operator overloading with integer template parameter specialization
我的向量类定义如下:
template <unsigned int SIZE>
class Vector : public Stringable
{
private:
float mData [SIZE];
public:
Vector ();
...
};
我还声明了此(数学)向量的某些操作员(在向量类外):
template <unsigned int SIZE>
Vector<SIZE> operator+ (const Vector<SIZE>& vec, float c);
template<>
Vector<3> operator+ (const Vector<3>& vec, float c);
template<>
Vector<4> operator+ (const Vector<4>& vec, float c);
template <unsigned int SIZE>
Vector<SIZE> operator+ (const Vector<SIZE>& vec1, const Vector<SIZE>& vec2);
template <>
Vector<3> operator+ (const Vector<3>& vec1, const Vector<3>& vec2);
template <>
Vector<4> operator+ (const Vector<4>& vec1, const Vector<4>& vec2);
这就是它们的实现方式:
template <unsigned int SIZE>
Vector<SIZE> operator+(const Vector<SIZE>& vec1, const Vector<SIZE>& vec2)
{
Vector<SIZE> result = Vector<SIZE>(vec1);
int i = 0;
for (i = 0; (i + 4) < SIZE; i += 4)
{
__m128 lhs = _mm_set_ps(vec1[i], vec1[i+1], vec1[i+2], vec1[i+3]);
__m128 rhs = _mm_set_ps(vec2[i], vec2[i+1], vec2[i+2], vec2[i+3]);
_mm_add_ps(lhs, rhs);
_mm_store_ps(result.getRawData(), lhs);
}
for (; i < SIZE; i++)
{
result[i] = vec1[i] - vec2[i];
}
return result;
}
template<>
Vector<3> operator+<3>(const Vector<3>& vec1, const Vector<3>& vec2)
{
Vector<3> result = Vector<3>(vec1);
float tmpBuffer [4];
__m128 lhs = _mm_set_ps(vec1[0], vec1[1], vec1[2], 0);
__m128 rhs = _mm_set_ps(vec2[0], vec2[1], vec2[2], 0);
_mm_add_ps(lhs, rhs);
_mm_store_ps(tmpBuffer, lhs);
mempcpy(result.getRawData(), tmpBuffer, 3 * sizeof(float));
return result;
}
template<>
Vector<4> operator+<4>(const Vector<4>& vec1, const Vector<4>& vec2)
{
Vector<4> result = Vector<4>(vec1);
__m128 lhs = _mm_set_ps(vec1[0], vec1[1], vec1[2], vec1[3]);
__m128 rhs = _mm_set_ps(vec2[0], vec2[1], vec2[2], vec1[3]);
_mm_add_ps(lhs, rhs);
_mm_store_ps(result.getRawData(), lhs);
return result;
}
template <unsigned int SIZE>
Vector<SIZE> operator+(const Vector<SIZE>& vec, float c)
{
Vector<SIZE> result = Vector<SIZE>(vec);
int i = 0;
for (i = 0; (i + 4) < SIZE; i += 4)
{
__m128 lhs = _mm_set_ps(vec[i], vec[i+1], vec[i+2], vec[i+3]);
__m128 rhs = _mm_set1_ps(c);
_mm_add_ps(lhs, rhs);
_mm_store_ps(result.getRawData(), lhs);
}
for (; i < SIZE; i++)
{
result[i] = vec[i] + c;
}
return result;
}
template <>
Vector<3> operator+<3>(const Vector<3>& vec, float c)
{
Vector<3> result = Vector<3>(vec);
float tmpBuffer [4];
__m128 lhs = _mm_set_ps(vec[0], vec[1], vec[2], 0);
__m128 rhs = _mm_set1_ps(c);
_mm_add_ps(lhs, rhs);
_mm_store_ps(tmpBuffer, lhs);
mempcpy(result.getRawData(), tmpBuffer, 3 * sizeof(float));
return result;
}
template <>
Vector<4> operator+<4>(const Vector<4>& vec, float c)
{
Vector<4> result = Vector<4>(vec);
__m128 lhs = _mm_set_ps(vec[0], vec[1], vec[2], 0);
__m128 rhs = _mm_set1_ps(c);
_mm_add_ps(lhs, rhs);
_mm_store_ps(result.getRawData(), lhs);
return result;
}
以上所有代码都在一个文件中:" vector.cpp"
我目前正在使用Intel的SSE Interinss从"正常"向量操作转移到SIMD操作。
由于尺寸为3&amp;4在我的应用程序中很常见,我想为这些操作员专业地使用这些模板操作员,以便更好地使用XMM寄存器。(如您所见,SIMD循环不会用于任何大小&lt; 4的向量)。
不幸的是,我对如何实现这一目标感到不知所措,我真的不知道我需要什么声明/定义,模板参数需要什么,...
编辑:现在,我会收到"多个定义"链接器错误,我正在使用clang 5.0
大约有50个错误(很多,50个只是一个猜测),所有专业似乎都存在...
CMakeFiles/Space.elf.dir/src/Entities/Entity.cpp.o: In function `Maths::Vector<3u> Maths::operator+<3u>(Maths::Vector<3u> const&, float)':
/home/.../CLionProjects/Space/src/Maths/Vector.cpp:427: multiple definition of `Maths::Vector<3u> Maths::operator+<3u>(Maths::Vector<3u> const&, float)'
CMakeFiles/Space.elf.dir/src/main.cpp.o:/home/.../CLionProjects/Space/src/Maths/Vector.cpp:427: first defined here
CMakeFiles/Space.elf.dir/src/Entities/Entity.cpp.o: In function `Maths::Vector<4u> Maths::operator+<4u>(Maths::Vector<4u> const&, Maths::Vector<4u> const&)':
/home/.../CLionProjects/Space/src/Maths/Vector.cpp:392: multiple definition of `Maths::Vector<4u> Maths::operator+<4u>(Maths::Vector<4u> const&, Maths::Vector<4u> const&)'
CMakeFiles/Space.elf.dir/src/main.cpp.o:/home/.../CLionProjects/Space/src/Maths/Vector.cpp:392: first defined here
/home/.../CLionProjects/Space/src/Maths/Vector.cpp:377: multiple definition of `Maths::Vector<3u> Maths::operator+<3u>(Maths::Vector<3u> const&, Maths::Vector<3u> const&)'
CMakeFiles/Space.elf.dir/src/main.cpp.o:/home/.../CLionProjects/Space/src/Maths/Vector.cpp:377: first defined here
CMakeFiles/Space.elf.dir/src/Entities/EntityManager.cpp.o: In function `Maths::Vector<3u> Maths::operator+<3u>(Maths::Vector<3u> const&, float)':
我已经审查了一部分路径,但是您得到了这个想法
好吧,我解决了问题,这就是方法。我将定义和声明分开,就像其他任何类别一样。然后,在实现文件(.cpp)的底部,我明确实例化了我的类,还可以实例化。
(不幸的是,加载/卸载的量已淘汰了SIMD指令,因为OT创建的开销比摆脱了。专业化全班可能是一个解决方案,但这是另一个时间)
相关文章:
- 如何使用默认参数等选择模板专业化
- 我可以用clang AST从模板专业化中获得默认的模板参数吗
- 带有默认参数的模板专业化
- 还有另一个类模板专业化(在布尔参数上)
- 常量函数参数的专业化
- 嵌套模板类的模板类模板模板参数的专业化
- 遍历模板参数包,没有争论的专业化的作用是什么?
- 继承专业化的模板参数推导
- 如何部分专业化功能以用元组元素作为参数调用功能
- 具有变异模板模板参数的方法的部分专业化
- 功能模板参数包,然后是模板参数和专业化
- 在允许的函数模板的明确专业化中扣除了多个模板参数
- C 中的模板专业化中的字符串参数
- 模板参数的模板专业化
- 对于类型是类模板专业化的参数,ADL背后的理由是什么
- 为什么我们不能在模板专业化的开始/中间使用可变参数模板(以及如何模拟)?
- 操作员与整数模板参数专业化过载
- 错误:类模板部分专业化包含无法推导的模板参数
- C - 具有非类型模板参数的模板类上的专业化函数模板
- 带有模板参数的模板专业化