C++為什麼允許s1+s2="D";這種語句?
s1,s2都是string。
在C++ Primer上看到的,它說新標準可以避免這種情況… 可是為什麼會允許給右值賦值…求解…
在C++裡面,並不一定只有左值才能調用operator=的。對於所有自定義類型,只要不是const,就可以用Operator=
人家明明在左邊……
~~~ 好吧,以下是迷惑的來源 ~~~
題主的思路大致應該是這樣的:
C++03 §5.2.2/10A function call is an lvalue if and only if the result type is a reference.
歌詞大意:函數調用表達式的值是什麼值,要看情況:
- 返回引用:左值
- 返回其它:右值
所以 s1 + s2 確實是個右值呀。
C++03 §5.17/1The assignment operator (=) and the compound assignment operators all group right-to-left. All require a modifiable lvalue as their left operand and return an lvalue with the type and value of the left operand after the assignment has taken place.
歌詞大意:等號左側一定要是可修改的左值。
s1 + s2 = "D" 左邊應該是左值呀,所以很矛盾呀。
看上去很有道理不是嗎?但是,之所以 s1 + s2 = "D" 可行,是因為:
C++03 §5/3Clause 5 defines the effects of operators when applied to types for which they have not been overloaded. Operator
overloading shall not modify the rules for the built-in operators, that is, for operators applied to types for which they are
defined by this Standard. However, these built-in operators participate in overload resolution, and as part of that process
user-defined conversions will be considered where necessary to convert the operands to types appropriate for the built-
in operator.
歌詞大意:本章內容只對內置操作符有效。
std::string::operator=() 不是內置操作符,而是重載……(通俗地說:逗你玩兒~)vector&
v.push_back(true);v[0] = false; // 這句和s1 + s2 = "xxx";有區別嗎?v;
==========================
因為有人質疑,於是補充一下:注意,vector&
其實即使是const, 也可能可以用operator=(),只要足夠賤,C++隨便玩兒……比如下面:
#include &
class TestClass {
public: mutable int b_; TestClass(int b):b_(b) {}; void operator=(int a) const {b_ = a;};};using namespace std;
int main(){ const TestClass tc(1);tc = 3;
cout &<&< tc.b_ &<&< endl; return 0;}我也來舉個栗子吧。下邊的程序會編譯錯誤:
int foo() {
int a = 0;
return a;
}
int main() {
--foo();
return 0;
}
原因是--只能用於左值。
然而下邊的程序卻不會編譯錯誤:int main() {
set&
s.insert(1);
s.erase(--s.end());
return 0;
}
因為這裡--被重載了,作用於一個臨時對象。
因為有運算符重載。
就像你調用
s1.Plus(s2).Assign("D");
一樣。
這是s1+s2產生的臨時對象再調用string類的成員函數operator=,c++標準里又沒說右值不能調用成員函數。
代碼貼全一點吧
string s1, string s2;
s1+s2="D";
string s3 = s1 + s2;
s3 = "D";
推薦閱讀:
※什麼時候應當依靠返回值優化(RVO)?
※認真學完 C++ Primer 後,C++ 語言到了什麼水平?
※為什麼C++編譯器不能發現未初始化的變數?
※數據結構課本中的「生命遊戲」有哪些奇葩的玩法?
※如何理解《Effective C++》第31條將文件間的編譯依賴關係降低的方法?
TAG:C |