【问题标题】:Move semantics in Eigen在 Eigen 中移动语义
【发布时间】:2014-11-16 17:25:58
【问题描述】:

我有几个关于 Eigen 的问题:

  1. 有谁知道近期是否有计划支持 Eigen 中的移动语义?在 Eigen3 网页的 TODO 列表中找不到任何内容。现在我正在使用swap 技巧来摆脱临时人员,比如

    MatrixXd foo()
    {
        MatrixXd huge_matrix(N,N); // size N x N where N is quite large
        // do something here with huge_matrix
        return huge_matrix; 
    }
    
    MatrixXd A(N, N); 
    A.swap(foo());
    

    我非常想用 C++11 风格编写上面的 swap

    A = foo();
    

    不必担心foo() 返回的临时值。

  2. C++98/C++03 编译器能否优化代码A = foo(); 来摆脱这个临时的?或者最安全的选择是使用swap()

【问题讨论】:

    标签: c++ c++11 move eigen


    【解决方案1】:

    Copy elision 可以很好地完成这项工作。即使是 C++03 编译器也会忽略临时的。
    特别是 NRVO(命名返回值优化),对于这段代码,

    MatrixXd foo()
    {
        MatrixXd huge_matrix(N,N);
        return huge_matrix; 
    }
    
    MatrixXd A = foo();
    

    A 内部构造huge_matrix。 C++03 标准在 [class.copy]/15 中指定:

    在以下情况下允许省略复制操作 情况(可以合并以消除多个副本):

    • 在具有类返回类型的函数中的return 语句中,当表达式是具有与函数返回类型相同的 cv 非限定类型的非易失性自动对象的名称时, 通过构造自动对象可以省略复制操作 直接进入函数的返回值
    • 当尚未绑定到引用 (12.2) 的临时类对象将被复制到具有相同的类对象时 cv-unqualified类型,复制操作可以通过构造省略 将临时对象直接放入省略副本的目标中

    【讨论】:

    • 谢谢,我不确定。特别是,我的fooA 作为常量引用的参数,所以基本上我有类似A = foo(A) 的东西。即使在这种情况下,复制省略也应该起作用,因为满足 as-if 规则,这是正确的吗?
    • 在我的代码 sn-p 中,似乎复制省略确实是由复制 ctor 执行的,在像 MatrixXd A = foo() 这样的一行中。但是,每当我重用A(例如A = foo();)时,赋值运算符都不会执行它,并且我将值传递给赋值运算符。
    • 哦,我明白了,因为我在赋值运算符中使用了cout,这具有可观察到的效果,所以它没有被省略(尽管复制ctors)stackoverflow.com/a/18610251/3093378
    • @vsoftco .. 在这样的赋值中,应该调用移动赋值运算符。并且还做了返回值优化,将本地对象构造成临时返回值。所以总成本应该是一个移动任务。
    • 我知道,移动语义可以做到这一点,但问题是如果我使用 C++11 之前的版本会发生什么。而且仍然不清楚(至少我无法验证)是否省略了赋值运算符,因为如果我将 cout 放入其中,则不会,请参阅上面的链接。
    猜你喜欢
    • 2014-01-17
    • 1970-01-01
    • 2016-07-11
    • 2012-04-09
    • 2020-08-29
    • 2018-04-05
    • 2019-01-02
    • 2021-09-24
    • 2011-07-28
    相关资源
    最近更新 更多