class 中 C++ 运算符重载的语法
Syntax for C++ operator overloading in a class
背景
我正在自学C++ this course. I am trying to overload an operator in a class using a friend function (Assignment 4.2).
编辑
链接的问题没有回答我的问题。该问题的公认解决方案提供了一种在 header + cpp 文件中实现模板的方法(并非全部在同一文件中)。
其实我已经参考了那个问题,部分了解了我的情况。
我的尝试
使用 Approach 2, I have almost gotten my code to work (see the cryptic error message). It turns out I am missing a <>
. (Solution manual).
我试过谷歌搜索,但没有人遇到过
的情况
- 友元函数,
- 运算符重载,并且
- 在模板中 class
同时。
我的理由
你不应该使用class public函数来做运算符重载,因为调用函数的对象将被隐式传递,占用一个函数参数。使重载运算符对称(在使用和定义上)是更好的代码风格。
讲义建议使用 friend
。
问题
- 为什么需要
<>
?
- 是否有更好的方法在模板化的 class 中进行运算符重载?
- (可选)如何理解错误消息?
谢谢。
代码
stack.h
#include <iostream>
#include <vector>
using std::cout;
using std::vector;
template <typename T>
class Stack;
template <typename T>
Stack<T> operator+(Stack<T> a, Stack<T> b);
template <typename T>
class Stack { // use default constructors and destructors
private:
vector<T> s;
public:
bool empty();
void push(const T &item);
T& top();
void pop();
friend Stack<T> operator+(Stack<T> a, Stack<T> b); // need operator+<>
};
stack.cpp
#include <iostream>
#include <vector>
using std::cout;
#include "stack.h"
template <typename T>
bool Stack<T>::empty() {
return s.empty();
}
template <typename T>
void Stack<T>::push(const T &item) {
s.push_back(item);
}
template <typename T>
T& Stack<T>::top() {
return s.back();
}
template <typename T>
void Stack<T>::pop() {
s.pop_back();
}
template <typename T>
Stack<T> operator+(Stack<T> a, Stack<T> b) {
Stack<T> temp;
while (!b.empty()) {
temp.push(b.top());
b.pop();
}
while (!a.empty()) {
temp.push(a.top());
a.pop();
}
Stack<T> c;
while (!temp.empty()) {
c.push(temp.top());
temp.pop();
}
return c;
}
int main() {
Stack<int> a, b;
a.push(1);
a.push(2);
b.push(3);
b.push(4);
Stack<int> c = a + b;
cout << c.top() << "\n";
return 0;
}
错误信息
Undefined symbols for architecture x86_64:
"operator+(Stack<int>, Stack<int>)", referenced from:
_main in stack-d2f02a.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1
您需要添加<>
(或<T>
)以使友元声明引用声明的运算符模板。如果没有它,友元声明将声明一个未定义的非模板 operator+
,这就是您收到链接器错误的原因。
顺便说一句:你也可以像
一样显式指定模板参数
// refers to the instantiation of template operator+ for T
friend Stack<T> operator+<T>(Stack<T> a, Stack<T> b);
// ^^^
当使用<>
时,模板参数T
将从函数参数中推导出来,并具有相同的效果。
// refers to the instantiation of template operator+ for T
// T is deduced from function parameters
friend Stack<T> operator+<>(Stack<T> a, Stack<T> b);
// ^^
背景
我正在自学C++ this course. I am trying to overload an operator in a class using a friend function (Assignment 4.2).
编辑
链接的问题没有回答我的问题。该问题的公认解决方案提供了一种在 header + cpp 文件中实现模板的方法(并非全部在同一文件中)。
其实我已经参考了那个问题,部分了解了我的情况。
我的尝试
使用 Approach 2, I have almost gotten my code to work (see the cryptic error message). It turns out I am missing a <>
. (Solution manual).
我试过谷歌搜索,但没有人遇到过
的情况- 友元函数,
- 运算符重载,并且
- 在模板中 class
同时。
我的理由
你不应该使用class public函数来做运算符重载,因为调用函数的对象将被隐式传递,占用一个函数参数。使重载运算符对称(在使用和定义上)是更好的代码风格。
讲义建议使用 friend
。
问题
- 为什么需要
<>
? - 是否有更好的方法在模板化的 class 中进行运算符重载?
- (可选)如何理解错误消息?
谢谢。
代码
stack.h
#include <iostream>
#include <vector>
using std::cout;
using std::vector;
template <typename T>
class Stack;
template <typename T>
Stack<T> operator+(Stack<T> a, Stack<T> b);
template <typename T>
class Stack { // use default constructors and destructors
private:
vector<T> s;
public:
bool empty();
void push(const T &item);
T& top();
void pop();
friend Stack<T> operator+(Stack<T> a, Stack<T> b); // need operator+<>
};
stack.cpp
#include <iostream>
#include <vector>
using std::cout;
#include "stack.h"
template <typename T>
bool Stack<T>::empty() {
return s.empty();
}
template <typename T>
void Stack<T>::push(const T &item) {
s.push_back(item);
}
template <typename T>
T& Stack<T>::top() {
return s.back();
}
template <typename T>
void Stack<T>::pop() {
s.pop_back();
}
template <typename T>
Stack<T> operator+(Stack<T> a, Stack<T> b) {
Stack<T> temp;
while (!b.empty()) {
temp.push(b.top());
b.pop();
}
while (!a.empty()) {
temp.push(a.top());
a.pop();
}
Stack<T> c;
while (!temp.empty()) {
c.push(temp.top());
temp.pop();
}
return c;
}
int main() {
Stack<int> a, b;
a.push(1);
a.push(2);
b.push(3);
b.push(4);
Stack<int> c = a + b;
cout << c.top() << "\n";
return 0;
}
错误信息
Undefined symbols for architecture x86_64:
"operator+(Stack<int>, Stack<int>)", referenced from:
_main in stack-d2f02a.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1
您需要添加<>
(或<T>
)以使友元声明引用声明的运算符模板。如果没有它,友元声明将声明一个未定义的非模板 operator+
,这就是您收到链接器错误的原因。
顺便说一句:你也可以像
一样显式指定模板参数// refers to the instantiation of template operator+ for T
friend Stack<T> operator+<T>(Stack<T> a, Stack<T> b);
// ^^^
当使用<>
时,模板参数T
将从函数参数中推导出来,并具有相同的效果。
// refers to the instantiation of template operator+ for T
// T is deduced from function parameters
friend Stack<T> operator+<>(Stack<T> a, Stack<T> b);
// ^^