gpt4 book ai didi

c++ - 使用模板重载 + 运算符

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:03:09 25 4
gpt4 key购买 nike

嘿,我在尝试使用重载的 + 运算符时收到链接器错误 LNK2019:未解析的外部符号。我将向您展示类里面的片段,以及我如何在 main 中使用它。如果您需要查看更多内容,请告诉我,我将尽量保持简洁。

/** vec.h **/
#ifndef __VEC_H_
#define __VEC_H_

#include <iostream>
#include <vector>

namespace xoor{

template<typename T>
class vec{

public:
inline friend vec<T> operator + (const vec<T>&, const vec<T>&);
inline const vec<T>& operator += (const vec<T>&);

private:
std::vector<T> m_index;
}; // Vec.


template<typename T>
vec<T>& operator + (const vec<T>& a, const vec<T>& b){
vec<T> product = a;
product += b;

return product;
} // Addition.

template<typename T>
const vec<T>& vec<T>::operator += (const vec<T>& v){
for (unsigned short i =0; i < m_index.size(); ++i){
if (i >= v.size())
break;
m_index[i] += v.getIndex()[i];
}

return * this;
} // Addition Compound.


} // xoor

#endif // __VEC_H_

请注意,我也有 [] 重载,所以我只是用它访问 m_index 的部分内容。 getIndex() 只返回 m_index。 size() 返回 m_index.size()

/** main.cpp **/

#include <iostream>
#include "vec.h"

void testHook();

int main(){
testHook();
system("PAUSE");
return 0;
}

void testHook(){
using namespace xoor;
vec<double> vA(3); // passing 3 for 3 elements
vec<double> vB(3);

// v + v
std::cout << "\n\tA + B = ";
vec<double> vAB(3);
vAB = vA + vB; // PRODUCES THE LNK2019
vAB.print(std::cout); // Outputs the vec class to the console.
}

错误信息:

Error   1   error LNK2019: unresolved external symbol "class xoor::vec<double> __cdecl xoor::operator+(class xoor::vec<double> const &,class xoor::vec<double> const &)" (??Hxoor@@YA?AV?$vec@N@0@ABV10@0@Z) referenced in function "void __cdecl testHook(void)" (?testHook@@YAXXZ)    main.obj

更新:

下面是类定义的正上方。如上所述,我继续收到相同的链接器错误。

    template<typename T> 
class vec;

template<typename T>
vec<T> operator + (const vec<T>&, const vec<T>&);

更新 2:解决方案。

以上更新不正确。 sbi 的解决方案确实有效,我只是未能按如下方式对运算符(operator)进行模板化。

    template<typename T> 
vec<T> operator +<T> (const vec<T>&, const vec<T>&);

sbi 和 david 正在讨论我为什么首先使用 friend 。最初我正在使用它们,因为你不能将两个参数传递给一个重载的二元运算符,例如 +,并立即寻求 friend 作为解决方案。事实证明,您仍然可以通过单个参数非常轻松地使用二元运算符。这是最终的解决方案。

// ...
template<typename T>
class vec{
public:
const vec<T> operator + (const vec<T>&, const vec<T>&)const;
// ...

}; // Vec.

template<typename T>
const vec<T> vec<T>::operator + (const vec<T>& v)const{
matrix<T> product = *this;
vec(product += v);
} // Addition.

此外,对于阅读本文的任何其他人,值得在他的答案底部查看 sbi 的注释。我一直在做的一些事情是多余的。

感谢大家的帮助。快乐编码。

最佳答案

<罢工>为了与模板成为 friend ,我认为您需要在要与它成为 friend 的类定义之前声明该模板。但是,要编译此声明,您需要前向声明类模板。所以这应该有效:

template<typename T> 
class vec;

template<typename T>
vec<T> operator + (vec<T>, const vec<T>&);

template<typename T>
class vec{
public:
friend vec<T> operator +<T> (vec<T>, const vec<T>&);
// ...

这与 operator+() 的特定实例成为 friend 函数模板,即operator+<T> . (您还可以与模板的所有实例成为 friend :

// no forward declarations necessary

template<typename T>
class some_class {
template<typename U>
friend void f(vec<U>&);
// ...
};

但是,它的用处不如另一个。)

编辑: David 的评论让我开始思考(应该从一开始就这样做!)并导致发现 friend声明是不必要的。你的 operator+只使用一个 public vec 的成员函数( operator+= ) 因此不需要是 friend类的。所以上面会简化为

template<typename T> 
class vec{
public:
// ...
};

template<typename T>
vec<T> operator + (vec<T> a, const vec<T>& b){
a += b;
return a;
}

这里还有一些注意事项:

  • operator+() (你在 operator+=() 之上很好地实现了,顺便说一句)应该在每个拷贝中使用它的左参数。
  • 不要声明函数为inline , 定义 它们。
  • operator+=()返回一个非 const引用,因为大家都期待f(m1+=m2)即使 f() 也能工作将其参数视为非 const引用。
  • 在类模板内部,在大多数地方您可以在引用类时省略模板参数列表。所以你可以说 vec& operator += (const vec&); . (但是,您不能在模板之外执行此操作 - 例如,在类之外定义该运算符时。)
  • A std::vector的索引类型拼写为 std::vector<blah>::size_type , 不是 unsigned short .

关于c++ - 使用模板重载 + 运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3331453/

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