有条件比较的优雅解决方案
What is elegant solution of conditional comparison?
我想基于标志的值以设计数/上升顺序排序数字向量。这样的东西:
int main()
{
vector<int> numbers;
bool is_negatif = false;
// Do some stuff
sort(numbers.begin(), numbers.end(), is_negatif ? less<int>(): greater<int>());
}
不幸的是,由于不同类型的较少/涂料结构,因此不会编译此类代码。
我正在使用这样的代码:
template<class _Ty>
struct MyComparator
{
template <bool Less>
static bool compare(const _Ty& _Left, const _Ty& _Right);
template <>
static bool compare<true>(const _Ty& _Left, const _Ty& _Right)
{
return _Left < _Right;
}
template <>
static bool compare<false>(const _Ty& _Left, const _Ty& _Right)
{
return _Left > _Right;
}
};
是用法:
sort(numbers.begin(), numbers.end(), is_negatif ? &MyComparator<int>::compare<true> : &MyComparator<int>::compare<false>);
这种问题的优雅解决方案是什么?
注意:bool值在编译时不知道!
如果您关心性能,那么对std::sort
的单个呼叫将不会切割。我刚刚检查了godbolt.org确保:GCC和Clang生成的组件都将任一功能指针加载到寄存器中,然后用于std::sort
中的每个比较。
std::function
由于类型的擦除而更糟。
movl bool compareLess<int>(int const&, int const&), %ebp
// ...
movl bool compareGreater<int>(int const&, int const&), %eax
// ...
call [std::__introsort_loop specialized for bool (*)(int const&, int const&)]
但是,如果您将std::sort
的两个专业分开:
if(is_negatif)
sort(numbers.begin(), numbers.end(), std::less<>{});
else
sort(numbers.begin(), numbers.end(), std::greater<>{});
您最终得到了两个类型的呼叫,在其中编译器可以将比较内联。
call [std::__introsort_loop specialized for std::less<void>]
// ...
call [std::__introsort_loop specialized for std::greater<void>]
(疯狂的长期专业名称缩写为清晰)
我找到了另一个解决方案。这似乎适合我。当然,也许有更优雅的解决方案
bool is_negatif = false;
// Do some stuff
std::function<bool(int, int)> func = less<int>();
if (!is_negatif)
func = greater<int>();
sort(numbers.begin(), numbers.end(), func);
您可以尝试使用类似的东西:
sort(numbers.begin(), numbers.end(),
is_negatif ? function<bool(int,int)>(less<int>()) :
greater<int>());
但是,这应该比普通的std::less<int>()
比较器的性能要差得多,因为此比较器可能不会被隔离。
在体内使用is_negatif
的比较器更易于直列,但它们会一次又一次地检查is_negatif
。
如果您想要出色的性能,请保持简单:
if (is_negatif)
sort (numbers.begin(), numbers.end(), less<int>());
else
sort (numbers.begin(), numbers.end(), greater<int>());
template <class T>
struct MyComparator
{
MyComparator(bool __is_negatif)
{
m_is_negatif = __is_negatif;
}
bool operator()(const T& x, const T& y) const
{
if(m_is_negatif)
{
return (x > y);
}
return (x < y);
}
private:
bool m_is_negatif;
};
vector<int> numbers;
bool is_negatif = false;
sort(numbers.begin(), numbers.end(), MyComparator<int>(is_negatif));
另一个解决方案就是将整个东西包裹在lambda中:
sort(numbers.begin(), numbers.end(), [&](int l, int r) {
return is_negatif ? l < r : l > r;
});
如果您担心有条件地影响性能过多,那就不要。任何半个体面的分支预测器都将弄清楚在排序期间应始终调用哪些比较。
lambda怎么样?
怎么样bool ascending = false;
auto sorting_condition = [&](const int & a, const int & b) -> bool {
if (ascending) return a > b;
else return !(a < b);
}
sort(numbers.begin(), numbers.end(), sorting_condition);
相关文章:
- 运行同一解决方案的另一个项目的项目
- Project Euler问题4的错误解决方案
- 计算每个节点的树高,帮助我解释这个代码解决方案
- C++:Application.cpp中抛出了未解析的外部符号(解决方案在问题的末尾,供未来的读者参考)
- visual c++,如何获取解决方案目录中的代码
- 有没有办法在远程设备上打开和编辑visual Studio 2017解决方案
- C++Matching Brackets 2解决方案不起作用
- 在 ubuntu3 上C++ goto 定义有什么解决方案吗16.04?
- 在 leetcode 上提交解决方案时出现堆栈缓冲区溢出错误
- 我的固定时间步长与增量时间和插值的解决方案是错误的吗?
- 无法在问题解决方案中执行输出逻辑
- 最大的回文产品 - 程序未运行,编写解决方案但无法理解问题
- 从预序遍历构造 bst 的 c++ 和 python 解决方案之间的区别
- 在一个解决方案中针对第三方静态库 (Creo) 的不同版本(版本)进行构建
- 如何巧妙地编写两个函数——一个用于检查是否存在解决方案,另一个用于获取所有解决方案
- 使用 Git 处理 C++ Visual Studio 2019 解决方案的外部依赖项源代码管理的最佳方法是什么?
- N-queen问题:无法弄清楚为什么我的解决方案不起作用
- 比较/搜索数组中多个整数的最佳解决方案
- sort() 方法 c++ 中的比较器函数.为大量数字获得不同的解决方案
- 有条件比较的优雅解决方案