У меня есть класс с Eigen::Quaterniond
в качестве защищенной переменной-члена. Я хочу получить к нему доступ через метод attitude()
. Есть три способа сделать это прямо сейчас, но ни один из них не работает.
Это минимальный рабочий пример в тестовом формате Google.
#include "gtest/gtest.h"
#include <Eigen/Geometry>
class MyClass{
public:
MyClass( double w, double x, double y, double z ) : attitude_(w,x,y,z) {}
Eigen::Quaterniond& attitude1() { return attitude_; }
const Eigen::Quaterniond& attitude1() const { return attitude_; }
// compilation fails with " error: 'IsVectorAtCompileTime' is not a member of 'Eigen::Quaternion<double>' "
// Eigen::Ref<Eigen::Quaterniond> attitude2() { return attitude_; }
// const Eigen::Ref<const Eigen::Quaterniond> attitude2() const { return attitude_; }
Eigen::Map<Eigen::Quaterniond> attitude3() { return Eigen::Map<Eigen::Quaterniond>(attitude_.coeffs().data()); }
const Eigen::Map<const Eigen::Quaterniond> attitude3() const { return Eigen::Map<const Eigen::Quaterniond>(attitude_.coeffs().data()); }
protected:
Eigen::Quaterniond attitude_;
};
TEST(QuaternionTest, const_reference ){
MyClass a(0.2,0.3,0.4,0.5);
const MyClass& b(a);
{
const double& pt1 = a.attitude1().w();
const double& pt2 = b.attitude1().w();
EXPECT_EQ(&pt1, &pt2); // FAILS
}
// {
// const double& pt1 = a.attitude2().w();
// const double& pt2 = b.attitude2().w();
// EXPECT_EQ(&pt1, &pt2);
// }
{
const double& pt1 = a.attitude3().w();
const double& pt2 = b.attitude3().w();
EXPECT_EQ(&pt1, &pt2); // FAILS
}
}
Комментируемый метод - это способ, которым я обычно возвращаю ссылки на внутренне хранимые Eigen-объекты, что позволяет мне затем принимать решение о фактическом хранении данных внутренне, не будучи известным за интерфейсом (то есть укладывая некоторый Vector3 в непрерывная часть памяти).
Ошибка компиляции выглядит для меня как ошибка, так как мы определенно знаем длину Quaternion во время компиляции, это на самом деле просто наряженный Vector4d.
Я делаю что-то явно неправильно?