简体   繁体   English

展开std :: reference_wrapper的成本

[英]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? 在第1行中,给定特定的用例(被间接解包的包装器,并且既未复制也未绑定到除函数参数之外的本地引用的绑定)给定实际使用的间接寻址,还是编译器仅检测到该对象已被间接解包并只是使用原始对象代替? 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. 我对gcc (版本7, -O3 -std=c++17 )特别感兴趣,尽管我猜clanggcc执行类似的优化技术。

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. 在优化的版本中使用std::reference_wrapper方法的预期成本为0,因为可以内联所有std::reference_wrapper代码。 The assembly output of statement os_wrapper(std::cout) << behaviour1(3); 语句os_wrapper(std::cout) << behaviour1(3);的汇编输出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. 内联是实现Stroustrup喜欢提到的零开销抽象的原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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