簡體   English   中英

具有相同底層類類型的條件運算符

[英]Conditional operator with same underlying class type

該程序應輸出0還是1? 在我閱讀和理解C ++ 14標准中引用的段落時,它應該打印1,但是GCC和clang都打印0(因為推導的類型是A const而不是A const& ):

#include <iostream>

struct A {};

int main()
{
    A a;
    A const& ra = std::move(a); // #1

    std::cout << std::is_same<decltype(true ? ra : std::move(a)),
                              A const&>::value; // Prints 0
}

在這種情況下, ra是一個A const值, std::move(a)是一個A x值,兩個類類型。 根據關於條件運算符(強調我的)的標准,結果應該是A const類型的lvalue ,因此decltype結果必須是A const&

[expr.cond] / 3否則,如果第二個和第三個操作數具有不同的類型並且具有(可能是cv限定的)類類型 ,或者兩者都是相同值類別的glvalues且除了cv-qualification之外的相同類型,嘗試將每個操作數轉換為另一個操作數的類型。 確定T1類型的操作數表達式E1是否可以轉換為匹配類型T2的操作數表達式E2的過程定義如下:

- 如果E2是左值 :如果E1可以被隱式轉換(第4節)到類型“左值引用T2” ,則E1可以被轉換為匹配E2,受制於轉換中引用必須直接綁定的約束(8.5。 3)到左值

[...]

在這種情況下, E2ra ,它是一個左值,另一個可以隱含地轉換為“左值參考T2” ,如第// #1行所示。 “對T2的左值引用”被翻譯為A const& ,因此, std::move(a)直接綁定到A const類型的左值,並且在轉換后,兩個操作數具有相同的類型和值類別,因此:

[expr.cond] / 3如果第二個和第三個操作數是相同值類別的glvalues並且具有相同的類型,則結果是該類型和值類別[...]。

因此,運算符結果應該是左值,並且decltype結果應該是引用,因此程序應該打印1。

問題是措辭笨拙。 你應該問一下表達式的類型和值類別是true ? ra : std::move(a) true ? ra : std::move(a)應該是。 這個問題的答案是A const類型的prvalue。 這隨后意味着程序應該打印0,因為我認為每個編譯器都正確。


?:的規則相當復雜。 在這種情況下,我們有兩個類類型的表達式,我們試圖看看是否可以基於有限的規則子集相互轉換。

嘗試轉換rastd::move(a)失敗。 我們首先嘗試使用目標類型A&& ,它不能直接綁定到ra 然后我們嘗試(3.3.1)中的備份計划,因為這兩個表達式具有相同的基礎類類型,但我們的目標表達式至少不像源表達式那樣是cv限定的,所以這也失敗了。

嘗試轉換std::move(a)ra失敗(3.1)因為我們需要直接綁定到左值(我們可以將rvalue綁定到const值左側,但是這里我們需要綁定一個左值)。 但是,在(3.3.1)備份成功,因為現在的目標類型至少與CV-合格作為源。

因此,我們應用轉換並繼續,好像第二個操作數是類型A const的左值,但第三個操作數現在是類型A const的prvalue(而不是類型A的xvalue)。

(4)失敗,因為它們的價值類別不同。

因此, 結果是一個prvalue 因為它們具有相同的類型, 所以結果是這種類型A const

暫無
暫無

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

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