Передайте v.cwiseAbs () функции, которая принимает Ref <VectorXd> - PullRequest
1 голос
/ 21 октября 2019

Кажется, что следующее не работает.

void Foo(Ref<VectorXd> v) {
  // modifies v
}

Eigen::VectorXd v;
Foo(v.cwiseAbs());

Со следующим сообщением об ошибке

ошибка: не удалось преобразовать 'Eigen :: ArrayBase :: cwiseAbs () constс Derived = Eigen :: ArrayWrapper, -1, 1, true>, -1, 1, false>>;Eigen :: ArrayBase :: CwiseAbsReturnType = Eigen :: CwiseUnaryOp, const Eigen :: ArrayWrapper, -1, 1, true>, -1, 1, false>>>;typename Eigen :: internal :: traits :: Scalar = double 'from' const CwiseAbsReturnType {aka const Eigen :: CwiseUnaryOp, const Eigen :: ArrayWrapper, -1, 1, true>, -1, 1, false>>>}'to' Eigen :: Ref> '

Есть предложения, почему и как это исправить?

1 Ответ

0 голосов
/ 21 октября 2019

Это не работает, потому что для обработки выражения, возвращаемого .cwiseAbs(), требуются два дополнительных квалификатора const. Это имеет смысл, потому что не должно быть возможности изменить результат v.cwiseAbs() функцией, которая принимает этот аргумент в форме ссылки. Компилируется следующий код:

void Foo(const Ref<const VectorXd>& v) {
  std::cout << v << std::endl;
}

int main() {
  Eigen::VectorXd v(3);
  v << 1,-2,3;
  Foo(v.cwiseAbs());
}

Однако с этой модификацией не разрешено изменять v в пределах Foo().

Самое простое решение - это, вероятно, сбросить Ref<>и вместо этого использовать

 Foo(VectorXd v) {...}

. Это создает локальную копию, но это не должно быть проблемой с точки зрения производительности, более того, так как невозможно избежать какой-либо копии, если v должен быть изменен в Foo(). Если Ref хранится в подписи Foo, можно сделать копию v.cwiseAbs() и позвонить Foo() с этой копией:

void Foo(Ref<VectorXd> v) {...}
...
Eigen::VectorXd w = v.cwiseAbs();
Foo(w);

Как предлагает @chtz, альтернативадоступно с C ++ 11:

void Foo(VectorXd&& v) {...}

Хотя это позволяет изменять v в пределах Foo(), его использование может быть несколько опасным, поскольку в Foo() изменяется только временное значение. Изменения v, сделанные в Foo(), не изменятся v в main().

...