[英]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有效的規則,這要簡單得多。
否decltype
會創建一個未評估的上下文 ,就像sizeof
一樣。 編譯器查看類型信息,而僅查看其他信息。
您不能在前導返回類型中使用參數。
decltype( builder.makeObject() ) makeAndProcessObject (const Builder& builder)
導致錯誤,因為生成builder
是未知標識符。 這就是創建尾隨返回類型的原因。
this
參數是否為const
是類型信息的一部分。 如果decltype
不執行重載解析,那將毫無用處。 如果您從未見過基於成員函數的const
-ness進行重載,那么這可能沒有任何意義,但是有可能兩個函數具有相同的名稱和參數,其中一個被稱為對象的const
視圖,另一個被稱為const
視圖。非const
。 並且返回類型可以不同(實際上,它們經常因const
而不同)。 答案:
1)否decltype
僅在編譯時計算表達式的類型,而不在運行時評估表達式。 由於這個原因, decltype
被稱為“未noexcept
上下文”,因為它是sizeof
和noexcept
。
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.