簡體   English   中英

C ++ 11-清除返回值語法和decltype關鍵字

[英]C++11 - Clearing out Return Value Syntax and decltype Keyword

這里開始閱讀,這個C ++ 11代碼對我來說似乎很奇怪:

template <typename Builder>
auto
makeAndProcessObject (const Builder& builder) -> decltype( builder.makeObject() )
{
    auto val = builder.makeObject();
    // do stuff with val
    return val;
}

我有幾個問題:

1)在執行實際調用之前,decltype(builder.makeObject())是否再調用一次makeObject函數?

2)如果不是,並且在編譯時一切都已知(因此有點像增強宏),那么以下語法為什么無效,而我需要新的返回值語法?

//WRONG    
template <typename Builder>
    decltype( builder.makeObject() )
    makeAndProcessObject (const Builder& builder)
    {
        auto val = builder.makeObject();
        // do stuff with val
        return val;
    }

[額外的問題-在答案上獎勵+1] 3)在這個問題中,一個人問為什么他的代碼無法編譯,而答案是成員函數makeObject缺少“ const”說明符。 我得到了答案,但是為什么不要求const。

什么使以下聲明

template <typename Builder>
auto
makeAndProcessObject (const Builder& builder) -> decltype( builder.makeObject() )

如果const Builder&對象引用具有const makeObject或非const makeObject? decltype(builder.makeObject())部分僅必須找出函數的返回類型是什么,它不必關心函數是否修改了作為參數傳遞的對象!

通常,在聲明之后,C ++中的內容才可用。 在您的示例中,您試圖在聲明之前使用builder:

template <typename Builder>
    decltype( builder.makeObject() ) // using builder here
    makeAndProcessObject (const Builder& builder) // but builder isn't declared until here
    {
        auto val = builder.makeObject();
        // do stuff with val
        return val;
    }

添加了函數返回類型的新語法來解決此問題。

template <typename Builder>
auto // dummy return type, meaning we will give it later
makeAndProcessObject (const Builder& builder)  // declaring builder here
-> decltype( builder.makeObject() ) // using builder here -- no problem.
{
    auto val = builder.makeObject();
    // do stuff with val
    return val;
}

關於您的獎勵問題:用這種語言說,您必須給decltype一個有效的表達式,而不是使用另一組關於哪些參數對decltype有效的規則,這要簡單得多。

  1. decltype會創建一個未評估的上下文 ,就像sizeof一樣。 編譯器查看類型信息,而僅查看其他信息。

  2. 您不能在前導返回類型中使用參數。

     decltype( builder.makeObject() ) makeAndProcessObject (const Builder& builder) 

導致錯誤,因為生成builder是未知標識符。 這就是創建尾隨返回類型的原因。

  • 在未評估的上下文中,類型信息很重要。 this參數是否為const是類型信息的一部分。 如果decltype不執行重載解析,那將毫無用處。 如果您從未見過基於成員函數的const -ness進行重載,那么這可能沒有任何意義,但是有可能兩個函數具有相同的名稱和參數,其中一個被稱為對象的const視圖,另一個被稱為const視圖。非const 並且返回類型可以不同(實際上,它們經常因const而不同)。

答案:

1)否decltype僅在編譯時計算表達式的類型,而不在運行時評估表達式。 由於這個原因, decltype被稱為“未noexcept上下文”,因為它是sizeofnoexcept

2)請注意,在此聲明中

template <typename Builder>
decltype( builder.makeObject() )
makeAndProcessObject (const Builder& builder)

編譯builder在看到聲明const Builder& builder builder之前先看到const Builder& builder而對於接受的聲明,在確定返回類型時,編譯器已經解析了它所需的所有信息。 auto關鍵字告訴編譯器保留更多信息時,稍后將提供返回類型。

3)問題不在於聲明

template <typename Builder>
auto
makeAndProcessObject (const Builder& builder) -> decltype( builder.makeObject() )

它實際上與功能主體有關。 更准確地說,以下行:

auto val = builder.makeObject();

由於builder是一個const Builder&只能在builder上調用const方法,而最初, makeObject()不是其中之一。 然后使此方法const解決此問題。

更新:閱讀了Ben Voigt答案之后 與我上面所說的相反,聲明中存在此問題,因為它使用了decltype(builder.makeObject())並且我在函數主體中使用的相同參數也適用於此。

暫無
暫無

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

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