gpt4 book ai didi

c++ - Eigen 中正确的模板初始化

转载 作者:搜寻专家 更新时间:2023-10-31 02:08:32 24 4
gpt4 key购买 nike

关于 Eigen 中正确的参数类型推导。

我想创建一个可以用 Matrix(MatrixXd) 或 Vector(VectorXd) 初始化的类。问题是 MatrixXdVectorXd 都是 Eigen 中的 typedefs:

// roughly
typedef Matrix<double, Dynamic, 1> VectorXd;
typedef Matrix<double, Dynamic, Dynamic> MatrixXd;

如果我尝试用 VectorXdMatrixXd 重载两个构造函数,我会收到 模糊构造函数调用 错误。

考虑以下示例:

#include <iostream>
#include <Eigen/Dense>

using namespace std;
using namespace Eigen;

class Container {
public:
VectorXd a;
MatrixXd b;

Container(VectorXd a): a(a), b(MatrixXd::Zero(3,3)) {
cout << "Initializing with vector" << endl;
}

Container(MatrixXd b): a(VectorXd::Zero(3)), b(b) {
cout << "Initializing with matrix" << endl;
}
};

int main() {
Container x(VectorXd::Ones(4));
cout << x.a << endl;
cout << x.b << endl;

Container y(MatrixXd::Ones(4, 4));
cout << y.a << endl;
cout << y.b << endl;

return 0;
}

我得到的确切错误:

main.cpp:23:15: error: call to constructor of 'Container' is ambiguous
Container x(Matrix<double, Dynamic, 1>::Ones(4));
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
main.cpp:13:5: note: candidate constructor
Container(Matrix<double, Dynamic, 1> a): a(a), b(MatrixXd::Zero(3,3)) {
^
main.cpp:17:5: note: candidate constructor
Container(Matrix<double, Dynamic, Dynamic> b): a(VectorXd::Zero(3)), b(b) {

所以问题是:我怎样才能确定要调用哪个构造函数?

最佳答案

完美转发,sfinae 约束构造函数确实适用于您的特定用例:

template<class T>
Container(T&& a,decltype(VectorXd{std::forward<T>(a)})* = 0): a(std::forward<T>(a)), b(MatrixXd::Zero(3,3)) {}

template<class T>
Container(T&& b,decltype(MatrixXd{std::forward<T>(a)})* = 0): a(VectorXd::Zero(3)), b(std::forward<T>(b)){}

但我建议不要使用它(或任何等效的东西),因为不能保证这适用于任何矩阵表达式或 future Eigen 版本中的这些表达式,因为这些转换不能保证就 sfinae 而言是友好的我知道。

我认为最好提供更合理的重载(取决于你的实际用例),也许像

class Container {
public:
VectorXd a;
MatrixXd b;

struct DefaultedT{};
static constexpr DefaultedT Defaulted{};

Container(VectorXd a,MatrixXd b): a(std::move(a)), b(std::move(b)) {}
Container(VectorXd a,DefaultedT): a(std::move(a)), b(MatrixXd::Zero(3,3)) {}
Container(DefaultedT,MatrixXd b): a(VectorXd::Zero(3)), b(std::move(b)) {}
};

int main() {
Container x(VectorXd::Ones(4),Container::Defaulted);
Container y(Container::Defaulted,MatrixXd::Ones(4, 4));
...

或者只编写一个采用矩阵表达式的构造函数并相应地执行初始化逻辑......

关于c++ - Eigen 中正确的模板初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47463760/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com