簡體   English   中英

展開std :: reference_wrapper的成本

[英]cost of unwrapping a std::reference_wrapper

鑒於:

#include <iostream>
#include <functional>

template<class T> // Just for overloading purposes
struct behaviour1 : std::reference_wrapper<T const>
{
    using base_t = std::reference_wrapper<T const>;
    using base_t::base_t;

    // This wrapper will never outlive the temporary
    // if used correctly
    behaviour1(T&& t) : base_t(t) {}
};

template<class T>
behaviour1(T&&) -> behaviour1<std::decay_t<T> >;

struct os_wrapper : std::reference_wrapper<std::ostream>
{
    using std::reference_wrapper<std::ostream>::reference_wrapper;

    template<class T>
    os_wrapper& operator<<(behaviour1<T> const& v)
    {
        *this << v.get(); // #1
        return *this;
    }

    template<class U>
    os_wrapper& operator<<(U&& t)
    { this->get() << t; return *this; }
};

int main() { os_wrapper(std::cout) << behaviour1(3); }

在第1行中,給定特定的用例(被間接解包的包裝器,並且既未復制也未綁定到除函數參數之外的本地引用的綁定)給定實際使用的間接尋址,還是編譯器僅檢測到該對象已被間接解包並只是使用原始對象代替? 否則,哪一種設計會更好(例如,僅保存對象副本的標量類型的部分專業化是否會更有效)?

我對gcc (版本7, -O3 -std=c++17 )特別感興趣,盡管我猜clanggcc執行類似的優化技術。

在優化的版本中使用std::reference_wrapper方法的預期成本為0,因為可以內聯所有std::reference_wrapper代碼。 語句os_wrapper(std::cout) << behaviour1(3);的匯編輸出os_wrapper(std::cout) << behaviour1(3);

movl    $3, %esi
movl    std::cout, %edi
call    std::basic_ostream<char, std::char_traits<char> >::operator<<(int)

內聯是實現Stroustrup喜歡提到的零開銷抽象的原因。

暫無
暫無

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

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