Неоднозначность при использовании списка инициализаторов в качестве параметра

0

Я озадачен следующим фрагментом кода:

#include <Eigen/Dense>
#include <vector>

class Foo {};

void f(Eigen::MatrixXd const &) {}
void f(std::vector<Eigen::MatrixXd> const &) {}

void g(Foo const &) {}
void g(std::vector<Foo> const &) {}

int main()
{
    Foo a, b, c;
    Eigen::MatrixXd x, y, z;

    // f({x, y}); ambiguity, why?!
    f({x, y, z}); // ok

    g({a,b}); // ok
    g({a,b,c}); // ok
}

Если я прокомментирую 3-ю строку кода в main(), я получаю неоднозначную ошибку вызова,

/Users/vlad/so.cpp: In function 'int main()':
/Users/vlad/so.cpp:17:13: error: call of overloaded 'f(<brace-enclosed initializer list>)' is ambiguous
     f({x, y}); //ambiguity, why?!
             ^
/Users/vlad/so.cpp:17:13: note: candidates are:
/Users/vlad/so.cpp:6:6: note: void f(const MatrixXd&)
 void f(Eigen::MatrixXd const &) {}
      ^
/Users/vlad/so.cpp:7:6: note: void f(const std::vector<Eigen::Matrix<double, -1, -1> >&)
 void f(std::vector<Eigen::MatrixXd> const &) {}

Вызов его с 3-мя элементами в списке инициализации.

Однако, если вместо использования Eigen-матриц я использую свой собственный класс Foo (см. Функцию g), все работает нормально. У меня нет абсолютно никакой подсказки, почему прокомментированная строка является двусмысленной при использовании Eigen. Есть идеи?

PS: Если я перегружаю f так, что он принимает std::initializer_list<Eigen::MatrixXd>, тогда проблема исчезает, не более двусмысленный вызов.

  • 0
    Является ли Eigen::MatrixXd агрегатом?
  • 0
    @KerrekSB, не уверен, вероятно нет. Почему? Если я сделаю Foo агрегатом, добавив члена POD, ничего не изменится.
Показать ещё 13 комментариев
Теги:
c++11
eigen
initializer-list

1 ответ

4
Лучший ответ

Вероятно, ошибка вызвана этим шаблоном конструктора.

template<typename T0, typename T1>
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE Matrix(const T0& x, const T1& y)
{ ... }

И конструктор, и конструктор vector initializer_list одинаково хороши в вызове функции f({x, y}); , что приводит к ошибке двусмысленности.

Здесь приведен пример с аналогичными конструкторами и вызовами функций, что также приводит к ошибке двусмысленности.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню