将 std::forward 与 Eigen::Ref 对象一起使用
Use of std::forward with Eigen::Ref objects
我有一个仿函数 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>
个参数调用它 exactly -- 而不是,例如,使用向量或向量段。我发现的解决方法如下:
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
不是 class、结构或联合类型;但它实际上是一个class。 如何解决这个错误?
P.S.: 我必须承认我不是 100% 有把握理解什么时候应该使用 T&&
和 std::forward
。我的理解是,它们会准确地为您提供您传递的内容,而无需额外的副本或隐式转换。
error: ‘Eigen::Ref<Eigen::Matrix<double, -1, 1> >&’ is not a class, struct, or union type
^
您需要std::remove_reference
使完美转发的版本生效:
#include <type_traits>
template <typename T, typename U>
void operator()(T&& x, U&& y) {
Impl<typename std::remove_reference_t<T>::PlainObject>(std::forward<T>(x),
std::forward<U>(y));
}
我有一个仿函数 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>
个参数调用它 exactly -- 而不是,例如,使用向量或向量段。我发现的解决方法如下:
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
不是 class、结构或联合类型;但它实际上是一个class。 如何解决这个错误?
P.S.: 我必须承认我不是 100% 有把握理解什么时候应该使用 T&&
和 std::forward
。我的理解是,它们会准确地为您提供您传递的内容,而无需额外的副本或隐式转换。
error: ‘Eigen::Ref<Eigen::Matrix<double, -1, 1> >&’ is not a class, struct, or union type ^
您需要std::remove_reference
使完美转发的版本生效:
#include <type_traits>
template <typename T, typename U>
void operator()(T&& x, U&& y) {
Impl<typename std::remove_reference_t<T>::PlainObject>(std::forward<T>(x),
std::forward<U>(y));
}