【发布时间】:2020-06-24 09:02:25
【问题描述】:
考虑以下代码:
std::vector<int> vec(n);
for (auto& elem : vec) {
std::cin >> elem;
}
auto count = 0;
while (!isGood(vec)) {
auto odd_it = std::find_if(vec.begin(), vec.end(), [] (int num) { return ~(num % 2); });
auto even_it = std::find_if(vec.begin(), vec.end(), [] (int num) { return num % 2; });
if(odd_it != vec.end() && even_it != vec.end()) {
std::swap(vec.at(std::distance(vec.begin(), odd_it)), vec.at(std::distance(vec.begin(), even_it)));
count++;
}
else {
count = -1;
break;
}
}
(我知道它不是完整的代码,但足以重现问题)
在这段代码中,auto odd_it(以及auto even_it)行将返回向量中的第一个奇数元素。但是,我希望 std::find_if 向我返回一个迭代器,该迭代器指向第一个奇数元素,它也有一个偶数索引(在这种情况下,巧合的是,它也是第一个奇数元素。)
所以,简而言之,问题基本上是找到函数当前正在“处理”的元素的索引(已传递给谓词)
【问题讨论】:
-
你不能用
std::find_if以简单优雅的方式做到这一点。从技术上讲,您可以(通过减去地址),但您最好为此功能编写自己的find_if。 -
你的意思是像
auto odd_it = std::find_if(vec.begin(), vec.end(), [] (int num) { static bool isOdd = true; isOdd = !isOdd; return ~(num % 2) && isOdd; }); -
它将返回索引是奇数还是偶数。每次调用谓词时都会翻转标志
isOdd,并且感谢static,它的值将在谓词调用之间保留。但我怀疑该标准是否保证严格按顺序调用谓词。但是,任何合理的实施都可以做到。不过,特殊功能似乎是更好的解决方案。 -
见horrible example。顺便说一句,C++ 标准库不是 STL。 STLhas gone.
-
“按顺序调用谓词” 是的,在您的机器上,在周三的这种情况下,启用了 degging,没有优化。未定义行为的有趣部分是它看起来可以正常工作。如果不设置
ExecutionPolicy,如果在不同的 CPU 上并行检查每个条件,甚至会导致更多的竞争条件。
标签: c++ predicate c++-standard-library