2016-07-05 44 views
-2

這裏const auto &&真的沒用嗎?

https://youtu.be/dTeKf5Oek2c?t=2939

斯蒂芬噸Lavavej說,在一次談話說const auto &&是沒有用的。

是不是下面的有效用例?

NonMovableNonCopyable create() { 
    // ... 
    return {}; 
} 

const auto && obj = create(); 

混凝土應用程序:在XLL代碼,MS Excel中一般不喜歡它xloper s到被複制或移動將其返回,因爲在複製或移動它將不能正確地釋放它們之後。

+3

你可以用'const auto&'完成同樣的事情。 – StoryTeller

+2

僅供參考,您可以在所需的時間點擊YouTube視頻,然後選擇「當前時間複製視頻網址」,該鏈接可直接鏈接到該時間點:https://youtu.be/dTeKf5Oek2c?t = 2937 – Tas

+3

您應該或許可以解釋爲什麼'const auto &&'在問題的主體中被認爲沒有用處。 – juanchopanza

回答

1

Const T &&是非常有用的,如果T有一個可變字段。一個常見的例子是bool m_movedFrom,它被初始化爲false,並在被移出時被設置爲true。這允許你的對象的其餘部分 - 例如資源句柄保持爲const。

class Resource // use this as a base class of const correct classes 
{ 
private: 
    mutable bool m_movedFrom; 

protected: 
    Resource() 
    : m_movedFrom(false) 
    { 
    } 

    Resource(const Resource&& other) 
    : m_movedFrom(false) 
    { 
     other.m_movedFrom = true; 
    } 

    bool isOwning() const // call from descendant's destructor 
    { 
     return m_movedFrom; 
    } 
}; 

編輯:一個更復雜的例子當對象本身是常量,而是一個全球性的狀態不是解釋(不是說這是解決這個的好方法,它是隻說明目的):

#include <iostream> 
#include <string> 
#include <vector> 
#include <algorithm> 

typedef std::string object_type; 
typedef std::string seek_type; 

class GoalSeeker 
{ 
private: 
    static std::vector<const GoalSeeker*> s_store; 

    const std::vector<const GoalSeeker*>::iterator m_iter; 
    const object_type        m_data; 

public: 
    GoalSeeker(const object_type& data) 
    : m_iter(s_store.insert(s_store.end(), this)), m_data(data) 
    { 
    } 

    GoalSeeker(const GoalSeeker&) = delete; 

    GoalSeeker(const GoalSeeker&& other) 
    : m_iter(other.m_iter), m_data(other.m_data) 
    { 
     *m_iter = this; 
    } 

    ~GoalSeeker() 
    { 
     if(*m_iter == this) 
     { 
      // cleanup m_data 
     } 
    } 

    static bool seek(const seek_type& needle) 
    { 
     return std::find_if(s_store.begin(), s_store.end(), 
      [&needle](const GoalSeeker* haystack) 
      { 
       return haystack->m_data.find(needle) != std::string::npos; 
      }) != s_store.end(); 
    } 
}; 

std::vector<const GoalSeeker*> GoalSeeker::s_store = {}; 

GoalSeeker fn() 
{ 
    return GoalSeeker("def"); 
} 

int main() { 
    GoalSeeker a("abc"     ); 
    GoalSeeker b("cde"     ); 
    GoalSeeker s((const GoalSeeker&&) fn()); 

    std::cout << GoalSeeker::seek("de") << " " << GoalSeeker::seek("fff"); 
} 
+1

不知道我在這裏理解你的意思。我對我來說不太合適。你能提供一個具體的例子嗎? –

+0

編輯提供一個例子。 – lorro

+0

好的,在你使用的代碼中有C++ 11函數返回'const T'。這是*不是一個好主意*。猜測它是由Scott Meyers讀過舊的C++ 11之前的東西,曾經主張C++ 03。在考慮可能的情況時,它並沒有出現在我的腦海裏,這是非常罕見的。所以,const &&並不完全合理。 –

0

而不是

const auto && obj = create(); 

...寫信只是

const auto object = create(); 

...或

const auto object{ create() }; 

=依賴於編譯器eliding拷貝構造函數調用,但我不知道任何現存的編譯器,它無法做到這一點。

獲得的清晰度比國際海事組織提供的擔保要重要得多(如果使用參考,請使用普通&參考)。也就是說,避免讓維護程序員浪費時間來理解參考的基本原理。如果明確指定了類型,那麼可能是多態引用的情況,Petru Marginean的詭計,但是auto這是不可能的,因此維護程序員在一段時間的付費時間內仍然摸不着頭。


在另一方面,const T&&可以是函數重載作爲參數類型有用搭上臨時作爲參數的情況下,以同樣的方式作爲&&限定符成員函數被認爲具有足夠有用將要通過在標準中。例如,即使我不建議這樣做,如果存儲了一個指向實際參數的指針供以後使用,那麼可能不希望存儲指向臨時指針的指針,該臨時指針最終會成爲懸掛指針:

struct Expr{ virtual ~Expr(){} }; 

struct Sum_expr: Expr 
{ 
    const Expr*  a_; 
    const Expr*  b_; 

    Sum_expr(Expr const& a,Expr const& b): a_(&a), b_(&b) {} 

    template< class A > 
    Sum_expr(A&&, Expr const&& b) = delete; 

    template< class B > 
    Sum_expr(Expr const&& a, B&&) = delete; 
}; 

auto main() 
    -> int 
{ 
    Expr a; 
    Expr b; 
    Sum_expr sum{ a, b }; 
    Sum_expr sum2{ a, Expr() };  //! Nope, won't compile. 
} 

注:這裏A&&B&&同時支持右值和左值實際參數,即他們不一定右值引用,因爲他們普遍引用

但是,不是重載和區分的情況下,我認爲我會使一個指針正式參數,即使一個指針技術上可以是一個空指針,因爲就我所見,它與我習以爲常的更清楚地傳達意圖。

Sum_expr(Expr const* a, Expr const* b);