返回特征矩阵和临时矩阵
Returning Eigen matrices and temporaries
考虑以下函数Foo
:
// ...
Eigen::Vector3d Foo() {
Eigen::Vector3d res;
// ...
return res;
}
int main () {
Eigen::VectorXd foo = Foo(); // (1)
return 0;
}
由于 return 值优化,行 (1)
不应创建任何临时文件。但请考虑以下情况:
// ...
int main () {
Eigen::VectorXd foo;
// ...
foo.head<3>() = Foo(); // (2)
return 0;
}
(2)
是否创建任何临时文件?更一般地说,像 (2)
中那样初始化矩阵的任何块是否会创建任何临时对象? 如果不是这种情况就太好了。否则,我可以重新定义 Foo
如下:
// ...
void AlternativeFoo(Eigen::Ref<Eigen::Vector3d> res) {
// Modify res
}
int main () {
Eigen::VectorXd foo;
// ...
AlternativeFoo(foo.head<3>()); // (3)
return 0;
}
(3)
是在不创建临时对象的情况下实现上述目标的唯一方法吗?
The line (1) should not create any temporaries due to return value optimization.
不,它必须为 Foo
的 return 值临时实现。
Foo
的 return 类型和变量 foo
的类型不匹配(直到 cv 限定):Vector3d
vs VectorXd
.
但这是允许复制省略的必要条件。
如果不是这种情况,则使用的构造函数首先既不是副本也不是移动构造函数。
所以省略不会发生,在将要调用的构造函数中,Foo
的 return 值绑定到引用参数,这将导致临时对象的具体化。
Does (2) create any temporaries? More generally, does initializing any block of a matrix as in (2) create any temporaries?
是的,Foo
return 值的临时值将再次具体化,这次是由于绑定到 operator=
.
中的引用参数引起的
Is (3) the only way to achieve the above without creating temporaries?
我想是的,但这可能并不重要。
假设 Foo
可以内联,这种区别可能会变得毫无意义,编译器将确定 Foo
中的操作是否可以直接在 foo
的存储上执行。
如果 Foo
无法内联,则复制向量的三个条目不太可能与函数调用有显着关联。在这种情况下,您的替代解决方案会强制执行额外的间接寻址,这可能比复制一些值的成本更高。
考虑以下函数Foo
:
// ...
Eigen::Vector3d Foo() {
Eigen::Vector3d res;
// ...
return res;
}
int main () {
Eigen::VectorXd foo = Foo(); // (1)
return 0;
}
由于 return 值优化,行 (1)
不应创建任何临时文件。但请考虑以下情况:
// ...
int main () {
Eigen::VectorXd foo;
// ...
foo.head<3>() = Foo(); // (2)
return 0;
}
(2)
是否创建任何临时文件?更一般地说,像 (2)
中那样初始化矩阵的任何块是否会创建任何临时对象? 如果不是这种情况就太好了。否则,我可以重新定义 Foo
如下:
// ...
void AlternativeFoo(Eigen::Ref<Eigen::Vector3d> res) {
// Modify res
}
int main () {
Eigen::VectorXd foo;
// ...
AlternativeFoo(foo.head<3>()); // (3)
return 0;
}
(3)
是在不创建临时对象的情况下实现上述目标的唯一方法吗?
The line (1) should not create any temporaries due to return value optimization.
不,它必须为 Foo
的 return 值临时实现。
Foo
的 return 类型和变量 foo
的类型不匹配(直到 cv 限定):Vector3d
vs VectorXd
.
但这是允许复制省略的必要条件。 如果不是这种情况,则使用的构造函数首先既不是副本也不是移动构造函数。
所以省略不会发生,在将要调用的构造函数中,Foo
的 return 值绑定到引用参数,这将导致临时对象的具体化。
Does (2) create any temporaries? More generally, does initializing any block of a matrix as in (2) create any temporaries?
是的,Foo
return 值的临时值将再次具体化,这次是由于绑定到 operator=
.
Is (3) the only way to achieve the above without creating temporaries?
我想是的,但这可能并不重要。
假设 Foo
可以内联,这种区别可能会变得毫无意义,编译器将确定 Foo
中的操作是否可以直接在 foo
的存储上执行。
如果 Foo
无法内联,则复制向量的三个条目不太可能与函数调用有显着关联。在这种情况下,您的替代解决方案会强制执行额外的间接寻址,这可能比复制一些值的成本更高。