[英]C++ Templates and a Linker Error
請考慮以下 C++ 程序:
#include <iostream>
using namespace std;
template <class T> class Array
{
T *pType;
int itsSize;
public:
// template <class T>
friend ostream &operator<< (ostream &, Array<T> & );
};
template <class T>
ostream &operator<< (ostream &output, Array<T> &theArray)
{
return (output);
}
ostream &operator<< (ostream &, Array<int> &);
int main ()
{
Array<int> theArray;
cout << theArray << endl;
return 0;
}
上面的代碼可以編譯,但鏈接器給出了以下錯誤:
未定義符號 `operator<<(std::ostream&, Array&)'
我相信我需要告訴編譯器為運算符 << 實例化一個函數,但我不知道該怎么做。
鮑勃
不,您不需要告訴編譯器實例化模板,它會在需要時自行完成所有操作。
你的線路
ostream &operator<< (ostream &, Array<int> &);
實際上告訴編譯器你有一些其他的Array<int>
運算符,所以它不應該使用該類型的模板。
所以鏈接器去尋找另一個操作符,但當然沒有找到。
如果你只是刪除那個額外的聲明,它應該工作得更好。
聲明
ostream &operator<< (ostream &, Array<int> &);
不是告訴編譯器實例化模板。 它聲明了一個單獨且獨特的非模板化函數,即重載。
在main()
, operator<<()
的用法解析為聲明的函數。 編譯器不需要專門化模板來查找匹配項。 但是,由於沒有該函數的定義(即實現),鏈接失敗。
刪除該聲明,您應該會發現您的代碼可以編譯和鏈接。
順便說一句,輸出流操作符通常不會更改正在輸出的對象。 因此,建議將模板化的ostream &operator<< (ostream &, Array<T> & )
更改為ostream &operator<< (ostream &, const Array<T> & )
此外,由於模板(通常)需要在頭文件中定義,並且頭文件包含在多個源文件中,因此最好避免using namespace std
,並將ostream
替換為std::ostream
。
您的代碼存在問題,@BoPersson 和@Perter 指出了一些問題。
但是,即使您更改了他們的建議(這是 ideone 上的現場演示)並且我也在我的 VS 2015 上運行了它。 編譯器仍然很生氣。
Ideone 說:
prog.cpp:10:55: warning: friend declaration 'std::ostream& operator&)' declares a non-template function [-Wnon-template-friend] friend ostream &operator & ); ^ prog.cpp:10:55: note: (if this is not what you intended, make sure the function template has already been declared and add after the function name here) /home/FHMhT9/ccNwcxP0.o: In function `main': prog.cpp:(.text.startup+0x1b): undefined reference to `operator&)' collect2: error: ld returned 1 exit status
VS 也給出了幾乎相同的錯誤。
Ideone 告訴我,類中的朋友聲明聲明了一個非模板函數。
因此,將類中的聲明更改為:
friend ostream &operator<< <T> (ostream &, Array<T> & );
// ^^^^^
// I added this <T> to tell the compiler that it is a template function.
但是需要在這之前定義函數,所以把operator<<
的實現剪掉,然后貼在類之前。 但是你需要一個類的前向聲明才能工作。 所以最后你的代碼變得非常像這樣:
我也將Array<T> &
更改為const Array<T> &
。
#include <iostream>
template <typename T>
class Array;
template <class T>
std::ostream &operator<< (std::ostream &output, const Array<T> &theArray)
{
output << "abc";
return (output);
}
template <class T> class Array
{
T *pType;
int itsSize;
public:
// template <class T>
friend std::ostream &operator<< <T> (std::ostream &, const Array<T> &);
};
int main()
{
Array<int> theArray;
std::cout << theArray << std::endl;
return 0;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.