工作小結(jié) 22.09.01

1. 歧義消除
C++中類似int(A)的代碼會引起語法歧義,其可以解釋為:

  • 對象聲明磷醋,即兩邊具有冗余圓括號的對象聲明余蟹,其等同于int A
  • 表達式語句,即函數(shù)式類型轉(zhuǎn)換燕锥,其等同于(int)A
  • 函數(shù)類型聲明辜贵,即A是類型名時,其等同于int (*fp)(A a)

對于表達式語句與對象聲明的二義性归形,C++標(biāo)準(zhǔn) 8.9 Ambiguity resolution 中提到

1 There is an ambiguity in the grammar involving expression-statements and declarations: An expression-statement with a function-style explicit type conversion as its leftmost subexpression can be indistinguishable from a declaration where the first declarator starts with a (. In those cases the statement is a declaration.
2 [Note: If the statement cannot syntactically be a declaration, there is no ambiguity, so this rule does not apply. The whole statement might need to be examined to determine whether this is the case. This resolves the meaning of many examples. [Example: Assuming T is a simple-type-specifier,

解釋:
(1) 在涉及表達式語句和聲明的語法中存在歧義托慨,則將函數(shù)式型轉(zhuǎn)解析為其最左邊的子表達式的一個聲明
(2) 若語法上不能是聲明,則不存在歧義暇榴,解析為函數(shù)式類型轉(zhuǎn)換
標(biāo)準(zhǔn)中的例子:

// Example: Assuming T is a simple-type-specifier
T(a)->m = 7;        // expression-statement
T(a)++;             // expression-statement
T(a, 5) << c;       // expression-statement

T(*d)(int);         // declaration
T(e)[5];            // declaration
T(f) = { 1, 2 };    // declaration
T(*g)(double(3));   // declaration

9.3.2 Ambiguity resolution 中還提到

1 The ambiguity arising from the similarity between a function-style cast and a declaration mentioned in 8.9 can also occur in the context of a declaration. In that context, the choice is between a function declaration with a redundant set of parentheses around a parameter name and an object declaration with a function-style cast as the initializer. Just as for the ambiguities mentioned in 8.9, the resolution is to consider any construct that could possibly be a declaration a declaration.

解釋:
此歧義還會出現(xiàn)在聲明的上下文中厚棵,例如函數(shù)類型的聲明。在這種情況下蔼紧,可在參數(shù)名稱周圍帶有一組冗余括號的函數(shù)聲明以函數(shù)樣式強制轉(zhuǎn)換作為初始值設(shè)定項的對象聲明之間進行選擇婆硬。解決方案是將任何可能是聲明的構(gòu)造視為聲明。
即將int(A)優(yōu)先考慮為對象聲明奸例,從而整體解析為參數(shù)名稱周圍帶有一組冗余括號的函數(shù)聲明彬犯。
標(biāo)準(zhǔn)中的例子:

struct S {
    S(int);
};

void foo(double a) {
    S w(int(a));    // function declaration
    S x(int());     // function declaration
    S y((int(a)));  // object declaration
    S y((int)a);    // object declaration
    S z = int(a);   // object declaration
}

2 An ambiguity can arise from the similarity between a function-style cast and a type-id. The resolution is that any construct that could possibly be a type-id in its syntactic context shall be considered a type-id.

解釋:
函數(shù)式類型轉(zhuǎn)換和類型標(biāo)識之間歧義。解決方案是,在其語法上下文中可能是類型標(biāo)識的構(gòu)造都應(yīng)被視為類型標(biāo)識躏嚎。
即語法上優(yōu)先視為類型標(biāo)識,若不合法菩貌,則視為函數(shù)式類型轉(zhuǎn)換表達式
標(biāo)準(zhǔn)中的例子:

template <class T> struct X {};
template <int N> struct Y {};
X<int()> a;                     // type-id
X<int(1)> b;                    // expression (ill-formed)
Y<int()> c;                     // type-id (ill-formed)
Y<int(1)> d;                    // expression

void foo(signed char a) {
    sizeof(int());              // type-id (ill-formed)
    sizeof(int(a));             // expression
    sizeof(int(unsigned(a)));   // type-id (ill-formed)

    (int()) + 1;                // type-id (ill-formed)
    (int(a)) + 1;               // expression
    (int(unsigned(a))) + 1;     // type-id (ill-formed)
}

3 Another ambiguity arises in a parameter-declaration-clause when a type-name is nested in parentheses. In this case, the choice is between the declaration of a parameter of type pointer to function and the declaration of a parameter with redundant parentheses around the declarator-id. The resolution is to consider the type-name as a simple-type-specifier rather than a declarator-id.

解釋:
當(dāng)類型名嵌套在圓括號中卢佣,參數(shù)聲明子句中會出現(xiàn)二義性。在這種情況下箭阶,可在聲明函數(shù)指針類型的參數(shù)和對象聲明周圍帶有冗余括號的參數(shù)之間進行選擇虚茶。解決方法是將類型名稱視為簡單類型說明符。
即將int(A)稱視為函數(shù)類型聲明仇参,其等同于int (*fp)(A a)
標(biāo)準(zhǔn)中的例子:

class C { };
void f(int(C)) { }  // void f(int(*fp)(C c)) { }
                    // not: void f(int C) { }
int g(C);
void foo() {
    f(1);           // error: cannot convert 1 to function pointer
    f(g);           // OK
}

注:上文提及的C++標(biāo)準(zhǔn)為 C++ 20 ISO/IEC 14882:2020 草案版本 N4849

2. 迭代器的operator++
在對關(guān)聯(lián)類容器遍歷進行刪除時嘹叫,會這樣做:

for (auto iter = m_map.begin(); iter != m_map.end();)
{
    if (刪除條件) {
        m_map.erase(iter++);
    } else {
        ++iter;
    }  
}

在對關(guān)聯(lián)類容器使用erase()去刪除時,會使當(dāng)前迭代器失效诈乒,那上文中的m_map.erase(iter++);在刪除之后罩扇,iter不就失效了嗎?為什么還能iter++怕磨,指向容器中的后一個元素喂饥?
看下迭代器對++操作的重載實現(xiàn):

// 以vector 迭代器為例,Windows版本如下
_Vector_const_iterator operator++(int) noexcept {
    _Vector_const_iterator _Tmp = *this;
    ++* this;
    return _Tmp;
}

可以看到實現(xiàn)中肠鲫,用局部對象_Tmp指向了當(dāng)前位置员帮,然后對迭代器進行了++操作,最后返回了局部對象_Tmp导饲。
所以捞高,iter++實際上已經(jīng)先對迭代器進行了++操作(此時,迭代器還未失效)渣锦,但最終返回了++前的值提供給erase()去刪除硝岗。
從源碼也可以看出,后置++需要多生成一個局部對象_Tmp袋毙,因此效率不及前置++辈讶。這也是為什么在循環(huán)中,一般對迭代器使用前置++的原因娄猫。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末贱除,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子媳溺,更是在濱河造成了極大的恐慌月幌,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,290評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件悬蔽,死亡現(xiàn)場離奇詭異扯躺,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評論 2 385
  • 文/潘曉璐 我一進店門录语,熙熙樓的掌柜王于貴愁眉苦臉地迎上來倍啥,“玉大人,你說我怎么就攤上這事澎埠∷渎疲” “怎么了?”我有些...
    開封第一講書人閱讀 156,872評論 0 347
  • 文/不壞的土叔 我叫張陵蒲稳,是天一觀的道長氮趋。 經(jīng)常有香客問我,道長江耀,這世上最難降的妖魔是什么剩胁? 我笑而不...
    開封第一講書人閱讀 56,415評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮祥国,結(jié)果婚禮上昵观,老公的妹妹穿的比我還像新娘。我一直安慰自己舌稀,他們只是感情好索昂,可當(dāng)我...
    茶點故事閱讀 65,453評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著扩借,像睡著了一般椒惨。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上潮罪,一...
    開封第一講書人閱讀 49,784評論 1 290
  • 那天康谆,我揣著相機與錄音,去河邊找鬼嫉到。 笑死沃暗,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的何恶。 我是一名探鬼主播孽锥,決...
    沈念sama閱讀 38,927評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼细层!你這毒婦竟也來了惜辑?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,691評論 0 266
  • 序言:老撾萬榮一對情侶失蹤疫赎,失蹤者是張志新(化名)和其女友劉穎盛撑,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體捧搞,經(jīng)...
    沈念sama閱讀 44,137評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡抵卫,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,472評論 2 326
  • 正文 我和宋清朗相戀三年狮荔,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片介粘。...
    茶點故事閱讀 38,622評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡殖氏,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出姻采,到底是詐尸還是另有隱情雅采,我是刑警寧澤,帶...
    沈念sama閱讀 34,289評論 4 329
  • 正文 年R本政府宣布偎谁,位于F島的核電站,受9級特大地震影響纲堵,放射性物質(zhì)發(fā)生泄漏巡雨。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,887評論 3 312
  • 文/蒙蒙 一席函、第九天 我趴在偏房一處隱蔽的房頂上張望铐望。 院中可真熱鬧,春花似錦茂附、人聲如沸正蛙。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽乒验。三九已至,卻和暖如春蒂阱,著一層夾襖步出監(jiān)牢的瞬間锻全,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工录煤, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留鳄厌,地道東北人。 一個月前我還...
    沈念sama閱讀 46,316評論 2 360
  • 正文 我出身青樓妈踊,卻偏偏與公主長得像了嚎,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子廊营,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,490評論 2 348

推薦閱讀更多精彩內(nèi)容