Возвращение ссылки на Eigen Quaternion - PullRequest
1 голос
/ 28 января 2020

У меня есть класс с 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.

Я делаю что-то явно неправильно?

...