最近最大的新闻莫过于微软发布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之分,下面是一个例子:
1
string one("cute");
2
3
const string two("fluffy");
4
5
string three()
{ return "kittens"; }
6
7
const string four()
{ return "are an essential part of a healthy diet"; }
8
9
10
11
one; // modifiable lvalue
12
13
two; // const lvalue
14
15
three(); // modifiable rvalue
16
17
four(); // 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
7
using namespace std;
8
9
10
11
void meow(string& s)
{
12
13
cout << "meow(string&): " << s << endl;
14
15
}
16
17
18
19
void meow(const string& s)
{
20
21
cout << "meow(const string&): " << s << endl;
22
23
}
24
25
26
27
void meow(string&& s)
{
28
29
cout << "meow(string&&): " << s << endl;
30
31
}
32
33
34
35
void meow(const string&& s)
{
36
37
cout << "meow(const string&&): " << s << endl;
38
39
}
40
41
42
43
string strange()
{
44
45
return "strange()";
46
47
}
48
49
50
51
const string charm()
{
52
53
return "charm()";
54
55
}
56
57
58
59
int 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
79
C:\Temp>cl /EHsc /nologo /W4 four_overloads.cpp
80
81
four_overloads.cpp
82
83
84
//output
85
86
meow(string&): up
87
88
meow(const string&): down
89
90
meow(string&&): strange()
91
92
meow(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&&:
例子:
1
C:\Temp>type two_overloads.cpp
2
3
#include <iostream>
4
5
#include <ostream>
6
7
#include <string>
8
9
using namespace std;
10
11
12
13
void purr(const string& s)
{
14
15
cout << "purr(const string&): " << s << endl;
16
17
}
18
19
20
21
void purr(string&& s)
{
22
23
cout << "purr(string&&): " << s << endl;
24
25
}
26
27
28
29
string strange()
{
30
31
return "strange()";
32
33
}
34
35
36
37
const string charm()
{
38
39
return "charm()";
40
41
}
42
43
44
45
int 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
65
C:\Temp>cl /EHsc /nologo /W4 two_overloads.cpp
66
67
two_overloads.cpp
68
69
70
71
// output
72
73
purr(const string&): up
74
75
purr(const string&): down
76
77
purr(string&&): strange()
78
79
purr(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
尹东斐 阅读(1800)
评论(3) 编辑 收藏 引用