我正在尝试重载“<<”模板类的运算符。我在.h文件中定义了类,并在.cpp文件中实现了它。
/tmp/ccjJIJhO.o: In function `main':
main.cpp:(.text+0xad): undefined reference to `std::basic_istream<char, std::char_traits<char> >& operator>><int>(std::basic_istream<char, std::char_traits<char> >&, FeatureVector<int>&)'
main.cpp:(.text+0xba): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& operator<< <int>(std::basic_ostream<char, std::char_traits<char> >&, FeatureVector<int> const&)'
collect2: ld returned 1 exit status
班级定义:
#include <iostream>
using namespace std;
#ifndef FEATURE_VECTOR_H
#define FEATURE_VECTOR_H
#include <common.h>
template < class FEAT_TYPE >
class FeatureVector;
template < class FEAT_TYPE >
istream & operator >> (istream &, FeatureVector<FEAT_TYPE> &);
template < class FEAT_TYPE >
ostream & operator << (ostream &, const FeatureVector<FEAT_TYPE> &);
template < class FEAT_TYPE >
class FeatureVector{
public:
FeatureVector(int = 0);
...
friend istream & operator >> <>(istream &, FeatureVector<FEAT_TYPE> & );
friend ostream & operator << <>(ostream &, const FeatureVector<FEAT_TYPE> &);
...
~FeatureVector();
private:
int m_nDim;
FEAT_TYPE * m_pFeat;
};
#endif
#include <featurevector.h>
...
template < class FEAT_TYPE >
istream & operator >> (istream & input, FeatureVector< FEAT_TYPE> & refFeat ){
int d;
for(d=0; d < refFeat.getDim(); d++){
input >> refFeat.m_pFeat[d];
}
return (input);
}
template < class FEAT_TYPE >
ostream & operator << (ostream & output, const FeatureVector< FEAT_TYPE > & refFeat ){
int d;
for(d=0; d < refFeat.getDim(); d++){
output << refFeat.m_pFeat[d] << " ";
}
output << endl;
return (output);
}
...
#include "featurevector-impl.cpp"
template class FeatureVector<int>;
//template istream & operator >> <>(istream &, FeatureVector<int> &);
//template ostream & operator << <>(ostream &, const FeatureVector<int> &);
#ifndef MY_LIB_H
#define MY_LIB_H
#include <featurevector.h>
#endif
#include <mylib.h>
#include <common.h>
int main(){
FeatureVector<int> pFeat(10);
cin >> (pFeat);
cout << (pFeat);
return (0);
}
INC=./inc
SRC=./src
LIB=./lib
OBJ=./obj
CC=g++
CFLAGS=-O3 -Wall
mylib: $(LIB)/mylib.a
echo "mylib was created!..."
$(LIB)/mylib.a: \
$(OBJ)/featurevector.o
ar csr $(LIB)/mylib.a \
$(OBJ)/featurevector.o
$(OBJ)/featurevector.o: $(SRC)/featurevector.cpp
$(CC) -c $(CFLAGS) $(SRC)/featurevector.cpp -I$(INC) \
-o $(OBJ)/featurevector.o
clean:
rm -rf $(LIB)/*.a
rm -rf $(OBJ)/*.o
LIB=../lib
INC=../inc
OBJ=../obj
BIN=../bin
CC=g++
CFLAGS=-O3 -Wall
LFLAGS=-lmylib -lm
$@.cpp: $(LIB)/mylib.a $@.cpp
cd ..; make; cd app;
$(CC) $(CFLAGS) $@.cpp -o $(BIN)/$@ -I$(INC) -L$(LIB) $(LFLAGS)
clean:
rm -rf $(BIN)/*
答案 0 :(得分:4)
根据this,您必须在类定义中将该函数称为模板。
<强> class.h 强>
#include <iostream>
using std::ostream;
template <typename T>
class A {
public:
...
template <typename J> // <-- CAUTION!
friend ostream &operator<<(ostream &output, const A<J> &a);
};
<强> class.cpp 强>
#include "class.h"
...
template <typename T>
ostream &operator<<(ostream &output, const A<T> &a) {
// Your implementation
return output;
}
...
template ostream &operator<<(ostream &output, const A<int> &a);
template ostream &operator<<(ostream &output, const A<float> &a);
如果删除了行template <typename J>
,则会出现编译错误“未定义引用”。
答案 1 :(得分:2)
答案 2 :(得分:1)
您发布的错误代码表示operator>>
引发了未解决的外部错误,而不是operator<<
。此外,您的代码将无法编译,因为myClass
上的转换构造函数没有int
。所以你还没有发布正确的代码。
但这有效:
#include <iostream>
using namespace std;
template < class T >
class myClass;
template < class T >
ostream & operator << (ostream &, const myClass<T> &);
template < class T >
class myClass{
public:
myClass(int) {}
friend ostream & operator << <>(ostream &, const myClass<T> &);
private:
T m_Data;
};
template < class T >
ostream & operator << (ostream & out, const myClass<T> & refClass){
out << refClass.m_Data << endl;
return (out);
}
myClass<int>;
myClass<float>;
int main(int argc, char **argv){
myClass<int> test(5);
cout << test;
return 0;
}
答案 3 :(得分:0)
featurevector-impl.cpp不正确。显式模板实例化如下所示:
template class FeatureVector<int>;
由于运算符不是成员,因此还必须明确实例化它们:
template istream & operator >> <>(istream &, FeatureVector<int> &);
我不建议像这样拆分你的模板定义,除非你真的热衷于微观管理哪些特定的类可以与你的模板一起工作(哪种违背了使用模板的精神)。
答案 4 :(得分:0)
不要让它变得如此复杂:
template<class FEAT_TYPE>
struct FeatureVector {
FeatureVector(int = 0);
friend std::istream& operator>>(std::istream &s, FeatureVector &x) {
for(int d = 0; d < x.getDim(); d++) {
s >> x.m_pFeat[d];
}
return s;
}
friend std::ostream& operator<<(std::ostream &s, FeatureVector const &x) {
// since you're terminating with " " rather than separating:
copy(x.m_pFeat, x.m_pFeat + x.getDim(), ostream_iterator<FEAT_TYPE>(s, " "));
s << endl;
return s;
}
//...