解包 std::reference_wrapper 的成本 [英] cost of unwrapping a std::reference_wrapper

查看:49
本文介绍了解包 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 行中,是实际执行的间接寻址,考虑到特定用例(立即解包的包装器,也未复制既不绑定到函数参数之外的本地引用),或者编译器是否会检测到该对象是立即展开并仅使用原始对象?否则哪种设计更好(例如,仅保存对象副本的标量类型的部分特化是否会更有效)?

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)?

我对 gcc(版本 7,-O3 -std=c++17)特别感兴趣,尽管我猜 clanggcc 执行类似的优化技术.

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

推荐答案

在优化构建中使用 std::reference_wrapper 方法的预期成本为 0,因为所有 std::reference_wrapper 代码可以内联.语句os_wrapper(std::cout)<<<的汇编输出行为1(3);:

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)

内联使 Stroustrup 喜欢提到的零开销抽象成为可能.

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

这篇关于解包 std::reference_wrapper 的成本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆