最近最大的新聞莫過于微軟發布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
尹東斐 閱讀(1826)
評論(3) 編輯 收藏 引用