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