在现行的C++标准中有这么一个名字,std,它是一个namespace(命名空间)。C++标准库的所有类型/对象/函数/模板都定义在这个命名空间中。关于”What namespace? Why namespace? How namespace?” 的问题,任何一本基础的C++读物中都会有介绍,此处略过。为了使用std内定义的对象,可供使用的语法无非是
1 2 3 4 5 6 7 | std::vector<int> ivec; //~ or using std::vector; vector<int> ivec; //~ or using namespace std; vector<int> ivec; |
现在有这样一种需要,我想为std内的某种类型(比如string)重载操作符,而不想使用std内为我们提供的版本。很简单:
1 2 3 4 5 6 7 8 9 10 11 12 13 | #include <iostream> #include <string> using namespace std; bool operator<(const string& l, const string& r) { return l > r; //~ 逆天而行了 :-) } int main(int argc, char **argv) { cout<<string("dutor")<string("ivan")<<endl; return 0; } |
运行这段代码,确实会得到我们想要的结果,dutor > ivan. 但是对于std内其他使用string的operator<()的对象还会这样吗?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #include <iostream> #include <string> #include <set> using namespace std; bool operator<(const string& l, const string& r) { return l > r; } int main(int argc, char **argv) { set<string> Set; Set.insert("ivan"); Set.insert("dutor"); for(set<string>::iterator it = Set.begin(); it != Set.end(); ++it) { cout<<*it<<endl; } return 0; } |
这次ivan会在dutor前面输出吗?很遗憾,dutor被首先输出。不要忘了,std内还有一个operator<(const string&, const string&)呢!set调用的正是std里面的版本!那么我们有什么办法可以让set调用我们自己的operator<()呢?这涉及到C++的名字查找机制,C++采用的是一种懒惰的名字查找机制,也可以说是一种非贪婪式的查找。以本例来说,set与原始版本的operator<同属于std命名空间,set就会就近使用这个版本,而不是我们的自定义版本,而我们在main中使用的却是自定义版本。
现在如何让set使用自定义的operator<已经变得明朗了,我们仅仅需要把我们的这个operator<添加到std中:
1 2 3 4 5 6 | namespace std{ bool operator<(const string& l, const string& r) { return l > r; } } |
关于C++的名字查找机制,这里提到的只是皮毛而已,很多参考资料中到都做了深入的描述,请自行查阅。
你好!除了代码,此处没有多少原创之物,皆为本人搜集、整理、总结之记录与心得,欢迎转载分享!转载时请尽量注明出处,将不胜感激。祝你健康、快乐!


Be the first to comment on this entry.