有码有真相,各位看官您上眼:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
int foo(int n)
{
	return n;
}
void bar(int n)
{
	return ;
}
struct wrap_int
{
	wrap_int(int _n): n(n) {}
	operator int() { return n; }
	operator int()const { return n; }
	wrap_int operator ++() { return ++n; }
	int n;
};
wrap_int foo(wrap_int n)
{
	return n;
}
int main()
{
	bar(++foo(372)); //~ 此行报错
	bar(++foo(wrap_int(372))); //~ 无错
	return 0;
}

  第一个bar调用中foo返回int型临时对象,想要把这个int临时对象++后传给bar,未遂。第二个bar调用中,foo返回一个包装过的int, 即wrap_int,对这个临时对象进行++(重载),得逞。结论:C++中,基本类型(内置类型)的临时对象不可以作为左值(l-value),即不可以修改;用户自定义类型的临时对象可以作为左值。
  再看:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int
main()
{
    vector<int> vec;
    vec.push_back(5);
    vec.push_back(4);
    vec.push_back(3);
    vec.push_back(2);
    vec.push_back(1);
    sort(++vec.begin(), vec.end());
    deque<int> deq;
    deq.push_back(5);
    deq.push_back(4);
    deq.push_back(3);
    deq.push_back(2);
    deq.push_back(1);
    sort(++deq.begin(), deq.end());
    return 0;
}

这段代码中,对deque的排序没有问题,而对vec的排序操作就可能造成和上例类似的错误。因为vector::iterator很可能会以裸露的指针来实现,这时对vec.begin()进行++操作就会出错。而对于deque,由于其特殊的内存模型,其iterator不可能是普通的指针,也就不存在这种错误。
~over

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)