简体   繁体   中英

cost of unwrapping a std::reference_wrapper

Given:

#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); }

In line #1, is the indirection actually performed, given that specific use case (a wrapper that is inmediatly unwrapped, and nor copied neither bound to local references except function parameters), or will the compiler just detect that the object is inmediatly unwrapped and just use the original object instead? Which will be a better design otherwise (for example, whether a partial specialization for scalar types that just save a copy of the object will be more efficient)?

I'm interested specifically in gcc (version 7, -O3 -std=c++17 ) although I guess both clang and gcc performs similar optimization techniques.

The expected cost of using methods of std::reference_wrapper in an optimized build is 0 because all std::reference_wrapper code can be inlined. The assembly output of statement os_wrapper(std::cout) << behaviour1(3); is :

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

Inlining is what enables zero-overhead abstractions which Stroustrup likes to mention.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM