2

I have written a function

template <int N>
bool checkColinear(const std::array<Eigen::Vector<double, N>, 3>& points) noexcept;

which takes three N-D points and returns true if they are collinear within a certain tolerance. Everything works if I call the function and explicitly specify N:

std::array<Eigen::Vector3d, 3> points = {Eigen::Vector3d{0.0, 1.0, 0.0},
                                         Eigen::Vector3d{0.0, 3.0, 0.0},
                                         Eigen::Vector3d{0.0, 2.0, 0.0}};

auto result = checkCollinear<3>(points);

But if I try to call the function without specifying N explicitly the compiler reports an error:

auto result = checkCollinear(points);

The error I get is "error C2672: 'checkCollinear': no matching overloaded function found". Is it possible for the compiler to deduce the template argument in this case? I am using MSVC143 (VS2022) and using C++20.

I have already tried to explicitly change the Eigen::Vector3d to Eigen::Vector<double, 3> and Eigen::Matrix<double, 3, 1>, but that neither of those fix it. I have also tried making the type of N a std::size_t too, but that doesn't help either.

  • 5
    [Looks like](https://godbolt.org/z/xebhY739h) an MSVC bug to me. – n. m. could be an AI Nov 21 '22 at 20:48
  • There is no way for the compiler to know N = 3. It would have to have semantic knowledge of how `Eigen::Vector`'s are encoded. – wcochran Nov 21 '22 at 21:40
  • 1
    @wcochran Template argument deduction process is successfull here, because after recursively 'unwrapping' argument type and parameter type we successfully descend (without encountering differences in template names or other arguments in corresponding positions of compared types) into obvious deduction base pattern (`N` against `3`). – YurkoFlisk Nov 21 '22 at 22:14
  • @wcochran I think it may be helpful to mention that `Eigen::Vector3d` is just a typedef of `Eigen::Vector` that is provided for convenience. – red-patriot Nov 21 '22 at 22:35
  • 2
    I stand corrected. It should be able to deduce this. – wcochran Nov 21 '22 at 23:05

1 Answers1

2

As mentioned in the comments, this is likely a bug. A workaround is to spell out the full type name for Vector<double, N> as:

Matrix<double, N,  1,          0,            N,         1>
                   ^           ^             ^          ^
                  col    row/col major    max rol    max col

And your function signature will become:

template <int N>
bool checkCollinear(const std::array<Eigen::Matrix<double, N, 1, 0, N, 1>, 3>& points) noexcept;

Demo

Ranoiaetep
  • 5,872
  • 1
  • 14
  • 39