在模板内部定义非成员函数(Define non-member functions inside templates)
来源:互联网 发布:yh线切割编程使用方法 编辑:程序博客网 时间:2024/06/01 09:37
《Thinking in C++》习题16.18,我的实现代码为:
//: C12:IostreamOperatorOverloading.cpp// Example of non-member overloaded operators#include "../require.h"#include <iostream>#include <sstream> // "String streams"#include <cstring>using namespace std;template<typename T, int sz = 5>class IntArray {T i[sz];public: IntArray() { memset(i, 0, sz* sizeof(*i)); } int& operator[](int x) { require(x >= 0 && x < sz, "IntArray::operator[] out of range"); return i[x]; } friend ostream& operator<<(ostream& os, const IntArray& ia); friend istream& operator>>(istream& is, IntArray& ia);};template<typename T, int size>ostream& operator<<(ostream& os, const IntArray<T,size>& ia) { for(int j = 0; j < size; j++) { os << ia.i[j]; if(j != size -1) os << ", "; } os << endl; return os;}template<typename T, int size>istream& operator>>(istream& is, IntArray<T,size>& ia){ for(int j = 0; j < size; j++) is >> ia.i[j]; return is;}int main() { stringstream input("47 34 56 92 103"); IntArray<int> I; input >> I; I[4] = -1; // Use overloaded operator[] cout << I;} ///:~
但是在VS2010下build时出现以下链接错误:
1>------ Build started: Project: MyCpp, Configuration: Debug Win32 ------
1> 16-18.cpp
1> LINK : D:\MyProjects\MyCpp\Debug\MyCpp.exe not found or not built by the last incremental link; performing full link
1>16-18.obj : error LNK2019: unresolved external symbol "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class IntArray<int,5> const &)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01@ABV?$IntArray@H$04@@@Z) referenced in function _main
1>16-18.obj : error LNK2019: unresolved external symbol "class std::basic_istream<char,struct std::char_traits<char> > & __cdecl operator>>(class std::basic_istream<char,struct std::char_traits<char> > &,class IntArray<int,5> &)" (??5@YAAAV?$basic_istream@DU?$char_traits@D@std@@@std@@AAV01@AAV?$IntArray@H$04@@@Z) referenced in function _main
1>D:\MyProjects\MyCpp\Debug\MyCpp.exe : fatal error LNK1120: 2 unresolved externals
怎么都想不明白。。。后来翻了一下《Effective C++》Item46 : Define non-member functions inside templates when type conversions are desired. 找到了答案。原因是模板在被调用时才会被实例化,上面代码中,当执行到IntArray<int> I;语句时模板IntArray才被实例化,应该实例化成下面这个样子:
class IntArray {int i[sz];public: IntArray() { memset(i, 0, sz* sizeof(*i)); } int& operator[](int x) { require(x >= 0 && x < sz, "IntArray::operator[] out of range"); return i[x]; } friend ostream& operator<<(ostream& os, const IntArray& ia); friend istream& operator>>(istream& is, IntArray& ia);};
这个时候,被实例化的IntArray中有了operator<<和operator>>的声明,但是并没有定义,所以会发生链接错误。修改方法之一是,将该非成员函数的定义放到模板内部,即
//: C12:IostreamOperatorOverloading.cpp// Example of non-member overloaded operators#include "../require.h"#include <iostream>#include <sstream> // "String streams"#include <cstring>using namespace std;template<typename T, int sz = 5>class IntArray {T i[sz];public: IntArray() { memset(i, 0, sz* sizeof(*i)); } int& operator[](int x) { require(x >= 0 && x < sz, "IntArray::operator[] out of range"); return i[x]; } friend ostream& operator<<(ostream& os, const IntArray& ia){for(int j = 0; j < sz; j++) {os << ia.i[j];if(j != sz -1) os << ", "; } os << endl; return os; } friend istream& operator>>(istream& is, IntArray& ia){for(int j = 0; j < sz; j++) is >> ia.i[j]; return is; }};int main() { stringstream input("47 34 56 92 103"); IntArray<int> I; input >> I; I[4] = -1; // Use overloaded operator[] cout << I;} ///:~
现在就可以编译和链接成功了。
参考
Bruce Eckel.《Thinking in C++》2nd Edition, Vol1.
Scott Meyers. 《Effective C++》. Item46
- 在模板内部定义非成员函数(Define non-member functions inside templates)
- [翻译] Effective C++, 3rd Edition, Item 46: 需要 type conversions(类型转换)时在 templates(模板)内定义 non-member functions(非成员函数)
- Effective C++ 46. Define non-member functions inside templates when type conversions are desired
- [翻译] Effective C++, 3rd Edition, Item 23: 用 non-member non-friend functions(非成员非友元函数)取代 member functions(成员函数)
- C++ - 使用非成员函数(non-member)处理函数的所有参数都需要类型转换
- [翻译] Effective C++, 3rd Edition, Item 24: 当希望将 type conversions(类型转换)应用于所有 parameters(参数)时,请声明为 non-member functions(非成员函数)
- Item 46:需要类型转换时,应当在类模板中定义非成员函数
- 4.2 Virtual Member Functions(虚拟成员函数)
- forbids in-class initialization of non-const static member不能在类内初始化非const static成员
- [翻译] Effective C++, 3rd Edition, Item 45: 用 member function templates(成员函数模板) 接受 "all compatible types"(“所有兼容类型”)
- 使用non-member函数
- How Non-Member Functions Improve Encapsulation ZZ
- 成员模板(member template)
- c++: Difference between member and non member functions
- Effective C++ 23. Prefer non-member non-friend functions to member functions
- Member Templates(成 员模板 )
- C++ - 成员函数(member function)模板(template) 详解 及 代码
- 成员函数(member function)模板(template) 详解 及 代码
- linux内核启动流程
- hdu 2955 Robberies
- UrlRewrite正则表达式匹配、配置实例和分析
- 8、vim c#开发工具 ---- Omnisharp
- [hackerrank]Counting Sort 3
- 在模板内部定义非成员函数(Define non-member functions inside templates)
- Oralce数据库的优化
- chrome下老是弹出网页显示 true
- codeforces 5C Longest Regular Bracket Sequence -- 贪心
- 验证matlab的diff函数比自己写c效率高很多
- ubuntu can't start eclipse and eclipse error
- c++开源项目汇总
- Haskell 学习笔记 1 --环境搭建与类型系统(Haskell Tutorial 1--Getting start with Haskell)
- 代码历程