Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Specializing toml::from for Eigen types #159

Closed
maspri opened this issue May 10, 2021 · 3 comments
Closed

Specializing toml::from for Eigen types #159

maspri opened this issue May 10, 2021 · 3 comments

Comments

@maspri
Copy link

maspri commented May 10, 2021

The following code will complain about toml::get being ambiguous.
The cause appears to be that Eigen::VectorXd believes it is constructible from a toml::value (static_assert is true). But in reality it is not.

#include <eigen3/Eigen/Dense>
#include <toml.hpp>

namespace toml {

    template<>
    struct from<Eigen::VectorXd>{
        static Eigen::VectorXd from_toml(const value& v){
            Eigen::VectorXd m;
            int rows = v.size();
            m.resize(rows);
            for (int i = 0; i < rows; ++i) {
                m << v.at(i).as_floating();
            }
            return m;
        }
    };

}

int main() {
    using namespace toml::literals;

    const auto root = u8R"(
        vec = [1,2,3]
    )"_toml;

    static_assert(std::is_constructible<Eigen::VectorXd , const toml::value&>::value, "");

    auto &v = toml::find(root,"vec");

    auto vec = toml::get<Eigen::VectorXd>(v);

    return 0;
}

I am not a complete stranger to template programming but, I can't figure out why Eigen::Vector thinks it is constructible
from a toml::value. I speculate it may be because Eigen tries to allow initializing from things that look like they are iterable?

Is there a workaround, or am i missing something else entirely?
Thank you for your time!

@ToruNiina
Copy link
Owner

Sorry for the late response and thank you for reporting the issue.

I reproduced the problem with Eigen 3.3.7 in my local environment. I will look into it. I will comment as soon as I figure out the reason.

@ToruNiina
Copy link
Owner

It seems that, as you suggested, it is because of the constructor of template<typename T> explicit Eigen::Matrix::Matrix(const T& x). It makes std::is_constructible<Eigen::Matrix, toml::value> true and it conflicts with the toml::from. In Eigen 3.3.7, it is defined at ${include}/eigen3/Eigen/src/Core/Matrix.h:291.

I think Eigen has it to make Matrix constructible from any of a scalar, a vector or a matrix. But since template<T> Matrix(const T& x) basically matches to almost anything, hence it makes Matrix constructible from toml::value.

I'm now trying to add precedence over the existing conversion methods, such as from<T> > from_toml > constructor, and it seems to be possible (at least with GCC). Once I have succeeded, I will merge it.

@ToruNiina
Copy link
Owner

I make toml::from and from_toml() always precede over a constructor. It makes your code compile, I think.

But, in your example, you defined vec elements as integers, so it will report a type error. It is required to be [1.0, 2.0, 3.0] or you need to check the types of elements in from_toml.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants