c++ - 在 Eigen 中实现 Clip()
问题描述
我有一些代码将一些值剪辑在以 0 为中心的范围之间,如下所示。
Eigen::VectorXd a;
Eigen::VecotrXd b;
a = a.cwiseMin(b).cwiseMax(-b); // no temporary created here?
我想将逻辑分解成一个函数。一种解决方案:
Eigen::VectorXd Clip(const Eigen::VectorXd& a, const Eigen::VectorXd& b);
a = Clip(a, b);
但我认为这是低效的,因为它会产生额外的临时性?
另一种解决方案:
void Clip(Eigen::Ref<Eigen::VectorXd> a, const Eigen::VectorXd& b) {
a = a.cwiseMin(b).cwiseMax(-b);
}
但这有时似乎不方便使用:
void SomeFunctionSignatureICannotChange(const Eigen::VectorXd& a, const Eigen::VectorXd& b) {
// Eigen::VectorXd a_clipped = Clip(a, b); would be cleaner.
Eigen::VectorXd a_clipped;
Clip(a_clipped, b);
}
我能想到的最佳解决方案:
template <typename DerivedV, typename DerivedB>
auto Clip(const Eigen::ArrayBase<DerivedV>& v,
const Eigen::ArrayBase<DerivedB>& bound)
-> decltype(v.min(bound).max(-bound)) {
return v.min(bound).max(-bound);
}
(我认为在这种情况下“汽车”很好,而不是常见的陷阱警告过的那个?)
但是,代码似乎模板繁重且有点复杂。例如,谷歌风格指南不鼓励尾随返回类型:
仅在需要它的情况下使用新的尾随返回类型形式(例如 lambda),或者通过将类型放在函数的参数列表之后,它允许您以更易读的方式编写类型。后一种情况应该很少见;这主要是相当复杂的模板代码中的一个问题,在大多数情况下不鼓励这样做。
或者,如果我删除尾随返回类型,函数返回类型扣除将开始。但谷歌风格指南似乎也不鼓励在公共标头中扣除函数返回类型
此外,仅当函数或 lambda 的范围非常窄时才使用它,因为具有推导返回类型的函数不定义抽象边界:实现就是接口。特别是,头文件中的公共函数几乎不应该推导出返回类型。
我是 Eigen 和 C++ 的新手,所以不确定我是否遗漏了什么。希望学习大家的意见和建议。谢谢!
解决方案
我确认a = a.cwiseMin(b).cwiseMax(-b);
不会产生任何临时性。在您的情况下,auto
强烈建议使用返回类型,我还认为您的用例是上述规则的完全合法的例外:
- 显式地编写返回类型将是一场噩梦并且容易出错。
- 这是一个非常短的函数,预计会被内联。因此,它有望同时被声明和定义。因此,第二条规则并不真正适用。
在 c++14 中,您甚至可以省略冗余:
template <typename DerivedV, typename DerivedB>
auto Clip(const Eigen::ArrayBase<DerivedV>& v,
const Eigen::ArrayBase<DerivedB>& bound)
{
return v.min(bound).max(-bound);
}
推荐阅读
- wordpress - woocommerce 类别存档页面上的 ACF 字段值显示
- android - android studio 编辑器中未出现的任何视图
- java - 如何在 java servlet 过滤器中检索所有 cookie,即使具有相同的名称和相同的域?
- azure - 如何正确测试 azure bot 服务
- database - 历史表树
- react-native - 在 React Native 按钮中创建新的触摸效果
- excel-formula - 停止在excel中自动将一般更改为日期
- perforce - 如何从待处理的cherrypick CL 中获取源分支?
- sql - 使用 Oracle 'with' 与使用表的行为不同
- react-native - react-native 上的 Tipsi-stripe 本地化