【发布时间】:2021-08-29 08:26:20
【问题描述】:
我有一个函子Foo,定义如下:
struct Foo {
template <typename _Vector>
void operator()(const Eigen::Ref<const _Vector>&, const Eigen::Ref<const _Vector>&) {
/* ... */
}
};
我想用特征向量、块或 Eigen::Ref 来调用它,_Vector 可以是任何特征向量类型。此实现不起作用,因为您必须完全使用Eigen::Ref<const _Vector> 参数调用它——而不是,例如,使用向量或向量段。我发现的解决方法如下:
struct Foo {
/* This works, but I'm not sure if it is the most correct solution. */
template <typename T, typename U>
void operator()(const T& x, const U& y) {
Impl<typename T::PlainObject>(x, y);
}
/* This doesn't work, but I expected this to be the most correct solution. */
// template <typename T, typename U>
// void operator()(T&& x, U&& y) {
// Impl<typename T::PlainObject>(std::forward<T>(x), std::forward<U>(y));
// }
template <typename _Vector>
void Impl(const Eigen::Ref<const _Vector>&, const Eigen::Ref<const _Vector>&) {
/* ... */
}
};
在这里,我将实现隐藏在函数Impl 中,并使用operator() 捕获每个参数;然后,我从第一个参数(x)的成员类型PlainObject 中推导出正确的_Vector 类型。但是,我希望注释代码更加“正确”,因为它完美地转发了参数,因此Impl 使用它们的方式与它们应该是完全一样的。 此断言是否错误?不幸的是,它失败并出现以下错误:
error: ‘Eigen::Ref<Eigen::Matrix<double, -1, 1> >&’ is not a class, struct, or union type
[build] 390 | Impl<typename T::PlainObject>(std::forward<T>(x), std::forward<U>(y));
[build] | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
它声明Eigen::Ref 不是类、结构或联合类型;但它实际上是一个类。 如何解决此错误?
P.S.:我必须承认,我不是 100% 有信心知道何时应该使用 T&& 和 std::forward。我的理解是,它们为您提供的正是您传递的内容,而无需额外的副本或隐式转换。
【问题讨论】:
-
T是否有一个名为PlainObject的 typedef?Impl是什么?你能把它变成minimal reproducible example吗? -
@TedLyngmo 我提供的代码已经很少了,只要您可以访问 Eigen 库就可以工作。
PlainObject是为所有 Eigen 类型定义的成员类型,定义了任何 Eigen 对象的底层类型,无论是块、段、Eigen::Ref 等。 -
好的,如果有的话,我希望我在答案中输入的内容有效。
标签: c++ templates reference eigen c++20