当前位置:  开发笔记 > 编程语言 > 正文

移动省略优化

如何解决《移动省略优化》经验,为你挑选了1个好方法。

考虑一个类的两个实现:

struct S1
{
    std::vector< T > v;
    void push(T && x) { v.push_back(std::move(x)); }
    void push(T const & x) { push(T(x)); }
    void pop() { v.pop_back(); }
    void replace(T && x) { pop(); push(std::move(x)); }
    void replace(T const & x) { replace(T(x)); }
};

struct S2
{
    std::vector< T > v;
    void push(T x) { v.push_back(std::move(x)); }
    void pop() { v.pop_back(); }
    void replace(T x) { pop(); push(std::move(x)); }
};

S1push重载表达正是我想要的.S2push是一种以不那么冗长的方式表达它的方式.

但我担心对象的过度移动构造存在缺陷.

现代编译器可以减少表达std::move(T(std::move(t)))std::move(t)一些t地方decltype(t)T&?现代编译器可以优化不必要的移动吗?或者这是否被标准禁止?



1> Yakk - Adam ..:

不,除了as-if优化之外,这种省略不合法.

现在,如果foo()是一个返回a的表达式T,那么S{}.push(foo())可以忽略从返回值foo()到参数的push移动:只进行一次移动.

但是,如果我们S{}.push(std::move(foo()),明确std::move阻止了省略的可能性.

通常更好的方法是基于动作的操作而不是基于推送的操作.

template
void emplace(Args&&...args) {
  v.emplace_back( std::forward(args)... );
}

这允许您传递参数以构造T对象,并使其直接构建在接收器(向量)中,而不是移动或复制到其中.

可选:

template()...))* =0
>
void emplace(Args&&...args) {
  v.emplace_back( std::forward(args)... );
}

如果你想要SFINAE支持.评论说"我们希望在T这里建造一个",如果不是很明显,也是礼貌的.

推荐阅读
Gbom2402851125
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有