首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >c++右值引用和移动语义

c++右值引用和移动语义
EN

Stack Overflow用户
提问于 2013-02-28 23:15:59
回答 1查看 875关注 0票数 6

所以我昨天在youtube上看了c++视频,偶然发现了一个关于C++-11右值引用和移动语义的视频。我想我从广义上理解了这个概念,但今天当我和助教一起浏览我的代码时,他问我为什么不在下面的代码中引用(比如std::pair<HostName, IPAddress>& p)。在这种情况下我根本没有想过这一点,但当他问我的时候,我记得视频中说“在C++-11中,你通常应该使用按值传递。”

我的问题是:在下面的代码中,std::pair<HostName, IPAddress> p会不会像std::pair<HostName, IPAddress>& p一样更好?移动语义会被使用吗?会有什么不同吗?

代码语言:javascript
复制
IPAddress NameServer::lookup( const HostName& host ) const {
    auto it = std::find_if( vec.begin(), vec.end(),
                       [host] ( std::pair<HostName, IPAddress> p ) {
        return p.first == host;
    } );
    ...
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-02-28 23:18:36

在这种情况下,您应该通过const引用传递。当您最终想要生成所传递的值的副本或移动时,通过值传递是有意义的;如果您既不想复制也不想移动,尤其是如果您想只观察,则应该传递(const)引用。

在这里,您的lambda谓词不需要生成它在输入中接收到的对的任何副本:因此,没有理由通过值传递(也没有理由通过vaue捕获)。

代码语言:javascript
复制
IPAddress NameServer::lookup( const HostName& host ) const {
    auto it = std::find_if( vec.begin(), vec.end(),
        [&host] ( std::pair<HostName, IPAddress> const& p ) {
    //   ^^^^^                                   ^^^^^^
        return p.first == host;
    } );
    ...
}

相反,考虑这种情况(典型的C++03代码):

代码语言:javascript
复制
struct A
{
    A(string const& s) : _s(s) { }
private:
    string _s;
};

在C++11中,由于您有移动语义,而不是通过常量引用传递s,您可以简单地通过值传递并将其移动到成员变量中:

代码语言:javascript
复制
struct A
{
    A(string s) : _s(move(s)) { }
private:
    string _s;
};

这是有意义的,因为我们总是最终生成所传递的值的副本。

正如Benjamin Lindley在注释中正确指出的那样,如果这是您可以接受的,您可以编写上述构造函数的重载,这些构造函数通过引用接受它们的参数:

代码语言:javascript
复制
struct A
{
    A(string const& s) : _s(s) { }    // 1 copy
    A(string&& s) : _s(move(s)) { }   // 1 move
private:
    string _s;
};

上面的版本只允许对左值执行一次复制,对右值执行一次移动,而通过值传递的版本总是执行一次额外的移动。因此,如果移动对于您的参数类型来说是一个开销很大的操作(对于string不是这种情况,但对于其他类型可能是这种情况),这种解决方案可能更可取。

但是,如果您的函数有多个参数,这样做可能会很麻烦。为了减少工作量,您可以编写一个单一的函数模板,该模板接受通用引用并完美转发其参数。This Q&A on StackOverflow与该主题相关。

票数 10
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15139080

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档