簡體   English   中英

通過引用使用std :: experimental :: optional作為參數

[英]Using std::experimental::optional as a parameter by reference

我的C ++編譯器是C++ 14 我有一個函數,它接收一個自定義類的對象,該對象封裝了各種錯誤代碼。 此參數通過引用傳遞。 自定義類對象有時會填充有效的錯誤值,有時可能為空。 我在C ++ 14中發現了一個看起來不錯的新事物,它是std :: experimental :: optional 現在,我嘗試將其用作參數,因為它實際上是一個optional參數。

以下是我嘗試使用的std :: experimental :: optional函數的簽名:

MyFunction(some param, std::experimental::optional<MyCustomErrorClass> & error_code) {

    //some logic
    //sometimes error_code is populated & sometimes not populated
}

以下是我如何調用MyFunction

MyCustomErrorClass error_code_object;
MyFunction(some_param, error_code_object);

但是我收到以下編譯器錯誤:

error: non-const lvalue reference to type 'std::experimental::optional< MyCustomErrorClass>' cannot bind to a value of unrelated type 'MyCustomErrorClass' MyFunction(some_param, error_code_object);

我嘗試搜索很多。 大多數std::experimental::optionalstd::optional使用示例都將其演示為函數的返回值。

我對std :: experimental :: optional的使用有什么問題?

這與std::experimental::optional無關; 這是關於嘗試將臨時綁定到左值引用,這是不可能的。

該臨時結果是從MyCustomErrorClass隱式轉換為optional<MyCustomErrorClass>

針對您的問題的正確MCVE如下:

void f(long&);

int main()
{
   int x = 42;
   f(x);
}

// error: invalid initialization of non-const reference of type 'long int&' from an
//          rvalue of type 'long int'

可以在intlong之間進行隱式轉換,但是結果臨時變量不能綁定到左值引用。

而是預構造optional對象,然后按名稱傳遞它。

optional<MyCustomErrorClass> opt_error_code_object = MyCustomErrorClass{};
MyFunction(some_param, opt_error_code_object);

您不想在此處通過引用接受可選內容。

引用可選是與可選引用完全不同的野獸。 第二個沒有被投票給C ++ 17,因為它具有令人困惑的語義,但是它更接近您想要的。

可選的在其內部存儲其數據的副本 因此,對可選對象的引用是對包含對象副本的容器的引用。

當您將錯誤對象傳遞給期望引用您錯誤類型的可選對象的函數時,它首先將錯誤對象復制到一個臨時可選對象中。 然后,它將嘗試將該臨時對象綁定到(左值)引用。 這是非法的。 因此您的代碼無法編譯。

如果您通過創建一個非臨時的可選對象或將臨時對象轉換為左值來“修復”它,您可能仍然無法獲得所需的內容,因為該函數現在與可選對象(而非原始錯誤對象)中的副本進行交互。

通常,當您通過引用傳遞對象時,您希望更改得以傳播。 但是它們不會超越可選內容中的副本。

一種解決方案是采用MyCustomErrorClass* -指針。 這是可為空的(如可選),並且不存儲副本。 只需在呼叫站點添加& ,然后在不希望傳遞時使用nullptr

您沒有給函數提供可選的MyCustomErrorClass ,而是給它提供了非可選的MyCustomErrorClass 並且您通過引用來提供它,這意味着您可以嘗試對其進行變異,並且它將嘗試對傳入的對象進行變異。但是您不能對實際上不是optional<T>事物執行可變的optional<T>操作optional<T> (好吧,我想,如果您真的想要……的話,您可以做……但是做這種事情的人會遇到不好的事情)。

暫無
暫無

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

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