Eigen3文档警告不要按值传递特征对象,,但它们只引用被用作函数参数的对象。
假设我使用的是特征3.4.0和C++20,如果我有一个带有特征成员的struct,这是否意味着构造函数中的传递值不能std::move?我需要传递引用并复制对象吗?还是用现代移动语义学来处理呢?
如果不能在构造函数中std::move特征对象,这是否意味着我应该从结构中显式删除移动构造函数?
例如,
#include <utility>
#include <Eigen/Core>
struct Node {
Eigen::Vector3d position;
double temperature;
// is this constructor safe to use?
Node(Eigen::Vector3d position_, const double temperature_)
: position(std::move(position_)), temperature(temperature_) {}
// or must it be this?
Node(const Eigen::Vector3d& position_, const double temperature_)
: position(position_), temperature(temperature_) {}
// also, should move-constructors be explicitly deleted?
Node(Node&&) = delete;
Node& operator=(Node&&) = delete;
};发布于 2022-01-21 09:55:31
艾根物体没有魔法。固定大小的类型(如Vector3d )的行为类似于std::array。像VectorXd这样的动态大小类型的行为类似于std::vector。
动态大小类型的传递值通常是错误的,因为它通常会调用副本结构,对于大型矩阵来说,这可能非常昂贵。引用传递(const,lvalue,rvalue)几乎总是正确的选择,脚注1。
对于固定大小的类型,按值传递可能是一个好处,因为前几个参数通常在寄存器中传递(取决于平台)。这样可以避免将值溢出到堆栈。然而,这并不适用于艾根。我猜他们宣称是个破坏者,即使他们不需要。这会将任何逐值传递转换为对隐藏副本的逐传递引用。您可以在哥德波特中看到这一点。在本征中,这似乎是一个遗漏的优化。
结论:使用参考资料.移动构造对于动态大小的特征数组来说是有意义的。对于固定大小的类型,它没有区别。
脚注1:一个罕见的例外情况可能是,如果您需要在函数中做一个副本。
https://stackoverflow.com/questions/70789238
复制相似问题