jc211
jc211

Reputation: 397

Eigen unaryExpr fails with MSVC but works with GCC

unaryExpr fails to transform a matrix of type X into type Y under a custom lambda in MSVC but works with GCC and clang. Has anyone encountered this before? Are there any workarounds? In the example I give, I use a matrix, but in my application, I use a sparse matrix so its not as easy as transforming the underlying array I don't think.

https://godbolt.org/z/TnKf7e

#include <Eigen/Core>
#include <string>

struct Expression {
    std::string d_ = "doesn't matter";
};

int main() {
    Eigen::Matrix<Expression, 3, 3> in;
    Eigen::Matrix3d out = in.unaryExpr([](const Expression& x) -> double { return 3.0; });
}

Upvotes: 1

Views: 238

Answers (1)

jc211
jc211

Reputation: 397

Setting the CXX standard is not enough in MSVC. This is because Eigen is checking the value of __cplusplus in Meta.h.

To make this code compile, add this compile option: /Zc:__cplusplus.

On CMake:

set_property(TARGET main PROPERTY CXX_STANDARD 17)
add_compile_options(/Zc:__cplusplus)

Relevant Code in Eigen:

#ifndef EIGEN_HAS_STD_RESULT_OF
#if EIGEN_MAX_CPP_VER>=11 && ((__has_feature(cxx_lambdas) || (defined(__cplusplus) && __cplusplus >= 201103L)))
#define EIGEN_HAS_STD_RESULT_OF 1
#else
#define EIGEN_HAS_STD_RESULT_OF 0
#endif
#endif

MSVC article about __cplusplus: https://devblogs.microsoft.com/cppblog/msvc-now-correctly-reports-__cplusplus/

Upvotes: 2

Related Questions