gpt4 book ai didi

c++ - 当模板类型的行为相同时,定义模板化类的成员函数的正确方法是什么?

转载 作者:行者123 更新时间:2023-11-28 00:28:22 26 4
gpt4 key购买 nike

考虑到如果某些东西没有损坏,我会破坏它,我决定专门化我拥有的一个类,以便它可以自动在 float 和 double 之间进行模板化。

我有以下[简化的]类声明:

// Quatcam.h
#pragma once
#include <boost/math/quaternion.hpp>
#include <boost/numeric/ublas/matrix.hpp>
template<typename FloatType>
class QuaternionCamera
{
public:
QuaternionCamera();
void applyTranslation(boost::numeric::ublas::vector<FloatType> translationVector);
boost::numeric::ublas::matrix<FloatType> getTranslationMatrix();

protected:
boost::numeric::ublas::vector<FloatType> m_location;
boost::math::quaternion<FloatType> m_orientation;

};

我已经在 .cpp 文件中定义了成员函数:

//Quatcam.cpp
#include "Quatcam.h"

using namespace boost::numeric::ublas;

template<typename FloatType>
QuaternionCamera<FloatType>::QuaternionCamera()
: m_location(3),
m_orientation(1,0,0,0)
{
m_location[0] = m_location[1] = m_location[2] = 0;
}

template<typename FloatType>
void QuaternionCamera<FloatType>::applyTranslation(boost::numeric::ublas::vector<FloatType> translationVector)
{
m_location += translationVector;

}
template<typename FloatType>
boost::numeric::ublas::matrix<FloatType> QuaternionCamera<FloatType>::getTranslationMatrix()
{
boost::numeric::ublas::matrix<FloatType> returnMatrix = boost::numeric::ublas::identity_matrix<FloatType>(4,4);

boost::numeric::ublas::vector<FloatType> invTrans = -m_location;
returnMatrix(3,0) = invTrans[0];
returnMatrix(3,1) = invTrans[1];
returnMatrix(3,2) = invTrans[2];
return returnMatrix;

}

此代码本身会很高兴地编译成 .lib 或 .obj 文件,但尝试就地使用该类会导致链接器错误。这是我尝试使用该类的示例 main.cpp:

#include "Quatcam.h"
#include <boost/numeric/ublas/io.hpp>
#include <iostream>

int main(int argc, char** argv)
{
QuaternionCamera<float> qcam;

boost::numeric::ublas::vector<float> loc(3);

loc[0] = 0;
loc[1] = 5;
loc[2] = 0;
qcam.applyTranslation(loc);

boost::numeric::ublas::matrix<float> qtm = qcam.getTranslationMatrix();
std::cout << "qtm: "<< qtm << std::endl;
return 0;

}

此代码无法链接并出现错误,因为缺少 getTranslationMatrix 和 applyTranslation 的符号。我假设这是因为我没有在技术上指定 float 类型的函数的完全特化。


问题

鉴于任何原子输入类型(float、double、甚至 int 等)的行为都是相同的,并且只会影响答案的精度。

有没有办法强制编译器为所有这些发出特化而不必这样做;

  1. 将所有函数定义移动到头文件中,或者;
  2. 为可能涉及大量复制粘贴的所有数据类型明确创建特化?

最佳答案

推荐链接


推荐做法

不是将定义从 .cpp 移动到标题,而是将 .cpp 重命名为 .tpp 并添加 #include "Quatcam.tpp"Quatcam.h 的末尾。

这是您通常拆分模板声明及其定义的方式,同时仍然具有可用于实例化的定义。

注意:如果你走这条路,你不应该编译.tpp本身,就像你对 .cpp 所做的那样.


显式实例化

您可以在您的 .cpp 中显式实例化相关模板以将它们提供给链接器,但这需要您知道您需要实例化的确切类型。

这意味着如果您只显式实例化 QuaternionCamera<float> ,如果 main.cpp 尝试使用 QuaternionCamera<double>,您仍然会收到链接器错误.

没有办法强制实例化所有“原子输入类型”,您必须将它们全部显式写出。

 template class QuaternionCamera<float>;  // explicit instantiation
template class QuaternionCamera<double>; // etc, etc...

关于c++ - 当模板类型的行为相同时,定义模板化类的成员函数的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23975366/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com