在现行的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++的名字查找机制,这里提到的只是皮毛而已,很多参考资料中到都做了深入的描述,请自行查阅。

  刚才在当当买书,又看到雷人的一幕(我为什么说又?):


实在想不通,这¥0.56是哪里来的?

Tags: .
你好!除了代码,此处没有多少原创之物,皆为本人搜集、整理、总结之记录与心得,欢迎转载分享!转载时请尽量注明出处,将不胜感激。祝你健康、快乐!
Home

Be the first to comment on this entry.

Name(required)
Mail (required),(will not be published)

RFC: Request For Comments. Orz..

Website(recommended)