最近最大的新闻莫过于微软发布Visual Studio2010了,对c++的支持更进一步,其intellsence的解析也使用了和以前完全不同的方法(以前是靠编译器,现在是独立inellsence单元),番茄可能要被打入冷宫了。
Stephan T. Lavavej在Visual c++ Team Blog上发布了VC10对C++0x标准的支持情况,包括:
lambdas, auto, static_assert and rvalue references,他的博客是针对CTP版本的。
我下载安装了VC10 beta1 professional,感觉除了卡,没啥不好的,新的intellsence和Java,C#一样,即时分析代码,并在有语法错误的地方画上红线。但是好像intellsence的语法不支持C++0x的,在右值引用,Lambda的地方,也画红线。
对于Stephan T. Lavavej写的
Rvalue References: C++0x Features in VC10, Part 2
我并没有打算全部翻译,有兴趣可以读原文,我只把我认为重要的地方翻译出来,顺序也调整了一下,水平有限,附上原文。
C++03 3.10/1 says: "Every expression is either an lvalue or an rvalue." It's important to remember that lvalueness versus rvalueness is a property of expressions, not of objects.
C++03 3.10/1 提到:"任何一个表达式,不是左值,就是右值",左值或者右值是针对表达式而言的,object没有左右值之分,应该时刻谨记这一点。
Both lvalues and rvalues can be either modifiable (non-const) or non-modifiable (const). Here are examples:
左值和右值都有const 和非const之分,下面是一个例子:
1string one("cute");
2
3const string two("fluffy");
4
5string three() { return "kittens"; }
6
7const string four() { return "are an essential part of a healthy diet"; }
8
9
10
11one; // modifiable lvalue
12
13two; // const lvalue
14
15three(); // modifiable rvalue
16
17four(); // const rvalue
18
Type& binds to modifiable lvalues (and can be used to observe and mutate them). Type& 只能绑定非const左值(可以观察和修改)。
const Type& binds to everything: modifiable lvalues, const lvalues, modifiable rvalues, and const rvalues (and can be used to observe them).
const Type& 可以绑定所有类型:非const左值,const左值,非const右值和const右值(只可以观察)。
上面这些都是03的标准,然而这对move语义和完美转发的实习,确实是一种障碍。关于move语义和完美转发,请看
《C++0x漫谈》系列之:右值引用 或“move语意与完美转发”(上)和
《C++0x漫谈》系列之:右值引用 或“move语意与完美转发”(下)。
move语义就是怎么能在非const右值销毁之前,将其中仍有用的资源窃取过来,以求高效。这就需要语言本身能识别非const右值,03中,语言本身不支持,只能靠入侵的方式实现。0x中,在语言层面上得到了支持,用&&表示非const右值。下面看看0x为了支持右值,进行了那些修正。
下面是关于函数左右值的重载决议:
1 . The initialization rules have veto power.
初始化规则具有否决权(否决权指对所有候选函数,如果有参数根本不能转化,就放弃考虑,比如把一个const type转化为type)。
2 . Lvalues strongly prefer binding to lvalue references, and rvalues strongly prefer binding to rvalue references.
左值优先绑定左值,右值优先绑定右值。
3 . Modifiable expressions weakly prefer binding to modifiable references.
非const表达式趋向于绑定非const引用。
正常情况下:
1#include <iostream>
2
3#include <ostream>
4
5#include <string>
6
7using namespace std;
8
9
10
11void meow(string& s) {
12
13 cout << "meow(string&): " << s << endl;
14
15}
16
17
18
19void meow(const string& s) {
20
21 cout << "meow(const string&): " << s << endl;
22
23}
24
25
26
27void meow(string&& s) {
28
29 cout << "meow(string&&): " << s << endl;
30
31}
32
33
34
35void meow(const string&& s) {
36
37 cout << "meow(const string&&): " << s << endl;
38
39}
40
41
42
43string strange() {
44
45 return "strange()";
46
47}
48
49
50
51const string charm() {
52
53 return "charm()";
54
55}
56
57
58
59int main() {
60
61 string up("up");
62
63 const string down("down");
64
65
66
67 meow(up);
68
69 meow(down);
70
71 meow(strange());
72
73 meow(charm());
74
75}
76
77
78
79C:\Temp>cl /EHsc /nologo /W4 four_overloads.cpp
80
81four_overloads.cpp
82
83
84//output
85
86meow(string&): up
87
88meow(const string&): down
89
90meow(string&&): strange()
91
92meow(const string&&): charm()
93
94
In practice, overloading on Type& , const Type& , Type&& , and const Type&& is not very useful. A far more interesting overload set is const Type& and Type&& :
在实践中,重载所有的4个版本没有意义,而我们更倾向于使用const string& 和string&&:
例子:
1C:\Temp>type two_overloads.cpp
2
3#include <iostream>
4
5#include <ostream>
6
7#include <string>
8
9using namespace std;
10
11
12
13void purr(const string& s) {
14
15 cout << "purr(const string&): " << s << endl;
16
17}
18
19
20
21void purr(string&& s) {
22
23 cout << "purr(string&&): " << s << endl;
24
25}
26
27
28
29string strange() {
30
31 return "strange()";
32
33}
34
35
36
37const string charm() {
38
39 return "charm()";
40
41}
42
43
44
45int main() {
46
47 string up("up");
48
49 const string down("down");
50
51
52
53 purr(up);
54
55 purr(down);
56
57 purr(strange());
58
59 purr(charm());
60
61}
62
63
64
65C:\Temp>cl /EHsc /nologo /W4 two_overloads.cpp
66
67two_overloads.cpp
68
69
70
71// output
72
73purr(const string&): up
74
75purr(const string&): down
76
77purr(string&&): strange()
78
79purr(const string&): charm()
80
81
For purr(up) , the initialization rules veto neither purr(const string&) nor purr(string&&) . up is an lvalue, so it strongly prefers binding to the lvalue reference purr(const string&) . up is modifiable, so it weakly prefers binding to the modifiable reference purr(string&&) . The strongly preferred purr(const string&) wins.
对于 purr(up) ,决议(1)没有否决 purr(const string&) 和 purr(string&&) ,up是左值,所以依照决议(2),它优先绑定左值purr(const string&) ,依照决议(3),它趋向于绑定非const右值 purr(string&&) ,所以左值胜出:purr(const string&) 。
For purr(down) , the initialization rules veto purr(string&&) due to const correctness, so purr(const string&) wins by default.
对于For purr(down),决议(1)以为const否决了 purr(string&&) ,所以选择purr(const string&)。
For purr(strange()) , the initialization rules veto neither purr(const string&) nor purr(string&&) . strange() is an rvalue, so it strongly prefers binding to the rvalue reference purr(string&&) . strange() is modifiable, so it weakly prefers binding to the modifiable reference purr(string&&) . The doubly preferred purr(string&&) wins.
对于purr(strange()),决议(1)都没有否决,strange() 是右值,所以依照决议(2),优先绑定右值purr(string&&),依照决议(3),strange() 是非const,趋向于绑定非const,所以purr(string&&) 两票获胜。
For purr(charm()) , the initialization rules veto purr(string&&) due to const correctness, so purr(const string&) wins by default.
对于purr(charm()), 初始化决议(1)否决了非const的purr(string&&) ,所以选择purr(const string&) 。
先写这么多吧,明天再写。
posted on 2009-05-27 23:17
尹东斐 阅读(1788)
评论(3) 编辑 收藏 引用