簡體   English   中英

VS2010中的條件運算符正確行為?

[英]Conditional operator correct behaviour in VS2010?

我想知道這段代碼是否表現出正確的C ++行為?

class Foo
{
public:
    Foo(std::string name) : m_name(name) {}

    Foo(const Foo& other) { 
        std::cout << "in copy constructor:" << other.GetName() << std::endl;
        m_name = other.GetName();
    }

    std::string GetName() const { return m_name; }
    void SetName(std::string name) { m_name = name; }

private:
    std::string m_name;
};

Foo CreateFoo(std::string name)
{
    Foo result(name);
    return result;
}

void ChangeName(Foo& foo)
{
    foo.SetName("foofoo");
}

int _tmain(int argc, _TCHAR* argv[])
{
    Foo fooA("alan");
    std::cout << "fooA name: " << fooA.GetName() << std::endl;
    bool b = true;
    ChangeName(b ? fooA : CreateFoo("fooB"));
    std::cout << "fooA name: " << fooA.GetName() << std::endl;
    return 0;
}

在VS2008中內置時,輸出為:

fooA name: alan
fooA name: foofoo

但是當在VS2010中構建相同的代碼時,它變為:

fooA name: alan
in copy constructor: alan
fooA name: alan

正在“alan”上調用復制構造函數,盡管通過引用傳遞(或者不是視情況而定),但fooA被調用的ChangeName保持不變。

C ++標准是否已更改,Microsoft是否修正了不正確的行為或是否引入了錯誤?

順便說一句, 為什么要調用復制構造函數

更全面的答案:

5.16 / 4和5:

“4如果第二個和第三個操作數是左值並且具有相同的類型,則結果屬於該類型並且是左值。

5否則結果是右值......“

換句話說,“bool?lvalue:rvalue”會導致暫時的。

這將是它的結束,但是你將它傳遞給一個函數,根據C ++,它必須接收一個左值作為參數。 因為你傳遞了一個rvalue,你實際上擁有的代碼不是C ++。 MSVC ++接受它,因為它是愚蠢的,並使用一堆它沒有告訴你的擴展,除非你把它變成一個掛件。 既然你所擁有的不是標准的C ++,並且MS只是通過擴展允許它,那么關於它的“正確”再也沒有什么可說的了。

在條件表達式中,第二個操作數是Foo類型的左值 ,而第三個是Foo類型的右值 (函數的返回值不返回引用)。

這意味着條件的結果是rvalue而不是左值 (無論第一個表達式的值是什么),然后您無法將其綁定到非const引用。 由於您違反了此規則,因此無法調用語言標准來說明編譯器版本的正確行為應該是什么。

條件的結果是左值如果兩個第二和第三運算數是相同類型的左值

編輯:從技術上講,兩個版本都違反了標准,因為當您違反標准的可診斷規則時都沒有發出診斷。

據我所知,這是由5.16第3點的C ++標准所涵蓋的,不是嗎?

它說“如果E2是一個右值,或者如果上面的轉換不能完成:如果E1和E2有類型,並且底層類型相同或者一個是另一個的基類:E1可以轉換為匹配E2如果T2的類型與T1類的基類相同,或者T2的cv資格與cv資格相同,或者cv資格等於cv資格。 T1。如果應用轉換,E1將更改為T2類型的右值,該值仍然引用原始源類對象(或其相應的子對象)。[注意:即,不進行復制。]“

這不是描述上面的情況嗎? 我認為確實如此,但我願意接受,如果有人可以解釋為什么不這樣做,我可能會錯。

謝謝。

奇怪的是,參考評論“Yep。將警告級別轉為4並再次編譯”。 (Noah Roberts),顯然有一個警告,提供'ChangeName'采用非const引用。 如果這是一個采用const-reference的函數,那么就沒有警告,但仍然創建了臨時變量。 也許這只是微軟編譯器的另一個流行病。

編譯器顯然正在評估:。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM