我已经编写了一个自定义矢量类模板和 print_vector 函数模板,它应该打印我的自定义矢量类的内容。print_vector 函数使用v.sz
和v.elem
在向量类中声明为私有。但是我无法在我的向量类中将 print_vector 声明为朋友。我想将 print_vector 单独定义在t_vector.cpp
.
一个问题是 print_vector 采用与在其中声明为友元的类具有相同类型的参数(成为循环依赖项?)。我还收到一条错误消息,说 print_vector 未在范围内声明。
我已经用// <--
// t_vector.h
#ifndef T_VECTOR_H
#define T_VECTOR_H
#include <string>
template <typename T>
void print_vector(Vector<T>& v);
template <typename T>
struct Vector {
private:
int sz;
T* elem;
public:
Vector() = delete;
explicit Vector(int s);
Vector(const Vector<T>& v);
~Vector();
Vector<T>& operator=(const Vector<T>& v);
T& operator[](int e) const;
template<typename U>
friend void print_vector(Vector<U>& v); // <-- TRYING TO FRIEND print_vector
};
#endif
// t_vector.cpp
#include "t_vector.h"
#include <stdexcept>
#include <iostream>
#include <string>
using std::cout;
using std::endl;
using std::string;
template <typename T>
Vector<T>::Vector(int s) {
if (s < 0) throw std::invalid_argument("Negative size");
cout << this << " called Vector(int s) constructor" << endl;
sz = s;
elem = new T[sz];
}
template <typename T>
Vector<T>::Vector(const Vector<T>& v) : sz{v.sz}, elem{new T[v.sz]} {
cout << this << " called Copy constructor on " << &v << endl;
for (int i = 0; i<sz; ++i) {
elem[i] = v[i];
}
}
template <typename T>
Vector<T>::~Vector() {
cout << "~" << this << " delete elem " << &elem << endl;
delete[] elem;
}
template <typename T>
Vector<T>& Vector<T>::operator=(const Vector<T>& v) {
cout << this << " called Copy assignment operator to copy " << &v << endl;
if (this != &v) {
T *tmp = new T[v.sz];
for (int i=0; i<v.sz; ++i ) {
tmp[i] = v.elem[i];
}
sz = v.sz;
delete[] elem;
elem = tmp;
}
return *this;
}
template <typename T>
T& Vector<T>::operator[](int e) const {
if (e < 0 || e >= sz) throw std::out_of_range("Vector::operator[]");
return elem[e];
}
template <typename T>
void print_vector(Vector<T>& v) { // <--- THIS FUNCTION WANTS TO READ v.sz WHICH IS PRIVATE
for (int i = 0; i < v.sz-1; ++i) {
cout << '[' << v.elem[i] << ']';
}
cout << '[' << v[v.sz-1] << ']' << endl;
}
// test_t_vector.cpp
#include "t_vector.h"
#include "t_vector.cpp"
#include <iostream>
using std::cout;
using std::endl;
int main() {
cout << "---------- Starting: test_vector ----------" << endl;
Vector<int> vec(3);
vec[2] = 5;
print_vector(vec);
cout << "---------- Exiting: test_vector ----------" << endl;
return 0;
}
错误输出:
g++ -O0 -Wall -Wextra -pedantic-errors -Wold-style-cast -fno-elide-constructors -std=c++14 -g -ggdb3 -MT t_vector.o -MMD -MP -MF t_vector.d -std=c++14 -I. -c -o t_vector.o t_vector.cpp
In file included from t_vector.cpp:1:
t_vector.h:7:6: error: variable or field ‘print_vector’ declared void
7 | void print_vector(Vector<T>& v);
| ^~~~~~~~~~~~
t_vector.h:7:19: error: ‘Vector’ was not declared in this scope
7 | void print_vector(Vector<T>& v);
| ^~~~~~
t_vector.h:7:27: error: expected primary-expression before ‘>’ token
7 | void print_vector(Vector<T>& v);
| ^
t_vector.h:7:30: error: ‘v’ was not declared in this scope
7 | void print_vector(Vector<T>& v);
| ^
make: *** [<builtin>: t_vector.o] Error 1