2017-09-14 43 views
1

我有運行時錯誤,當使用的std ::可選更換了一些代碼:爲什麼std :: optional :: value()&&;返回&&?

舊代碼:

T getValue(); 
... 
const auto& value = getValue(); 
value.get(); 

新代碼:

std::optional<T> getValue(); 
... 
const auto& value = getValue().value(); 
value.get(); // Runtime error, crash 

這是不可預知的我。 崩潰的原因是該方法返回T&&

我的問題是在什麼情況下T&&可能是有用的,所以該方法不返回T

完整代碼:

#include <experimental/optional> 
#include <iostream> 
#include <memory> 

struct Value { 
    std::unique_ptr<int> a = std::make_unique<int>(5); 
}; 

std::experimental::optional<Value> getValue() { 
    Value v; 
    return v; 
} 

int main() { 
    const Value& value = getValue().value(); 
    std::cout << *value.a << std::endl; 
    return 0; 
} 
+5

請**您的問題與[mcve]或[SSCCE(Short,Self Contained,Correct Example)](http://sscce.org) – NathanOliver

+0

此外,[this](https:/ /stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope)可能是相關的,如果你正在返回一個參考。 – NathanOliver

+0

如果它返回'/ * const */T&'BTW,你會遇到類似的問題。 – Jarod42

回答

3

它是由兩個相互競爭的需求,一個小的設計缺陷。

首先,避免了額外的移動,並且第二使能參考壽命延長。

這兩個在當前的C++競爭;你通常不能同時解決這兩個問題。所以你會看到代碼很隨意地做一個或另一個。

我個人發現返回一個右值引用以產生比從一個即將被銷燬的對象移出更多的問題,但那些標準化爲std::optional的人不同意。

我首選的方案將有其他方面的不足。

爲了解決這個問題,不具備做出這些妥協,我們需要的壽命延長是如何工作的複雜凌亂的重新定義。所以我們現在必須忍受這些問題。

1

返回T力移動構造它,而返回(rvalue-)參考無成本。

讓假設你有

std::optional<std::array<T, N>> getOptional(); 

然後

getOptional().value() 

會做幾個副本(RVO在這裏並不適用,因爲它會返回一個(移動)成員)。

相關問題