我在godbolt上测试了以下程序:
#include <algorithm>
#include <iostream>
#include <ranges>
#include <sstream>
int main() {
using namespace std::string_literals;
std::istringstream iss{"\x{01}\x{02}\x{03}\x{04}"};
auto view = std::views::istream<char>(iss) | std::views::chunk(2) |
std::views::transform([](auto t) {
return std::ranges::fold_left(t, 0, std::plus{});
});
for (const auto& p :
std::views::cartesian_product(view, std::views::iota(0, 3))) {
const auto [s, i] = p;
std::cout << s << ", " << i << '\n';
}
return 0;
}
GCC 和 clang 的结果是:
3, 0
0, 1
0, 2
7, 0
0, 1
0, 2
既然第一个
std::views::cartesian_product
参数应该是 仅通过一次,那么它不应该是以下吗?
3, 0
3, 1
3, 2
7, 0
7, 1
7, 2
我在评论中看到一个相关问题,然后被删除:取消引用
view.begin()
迭代器三次给出 3, 0, 0,这应该是根本原因。
这与
std::views::cartesian_product
无关,后者可以正常工作。这与您的 std::istringstream
iss
或(如评论中所述)及其在 std::views::istream<char>(iss)
中的用法有关。
将其替换为矢量,一切都会按预期工作:
#include <algorithm>
#include <iostream>
#include <ranges>
#include <sstream>
#include <vector>
int main()
{
using namespace std::string_literals;
std::vector<int> iss{ 1, 2, 3, 4};
auto view = iss | std::views::chunk(2) |
std::views::transform([](auto t) {
return std::ranges::fold_left(t, 0, std::plus{});
});
for (const auto& p :
std::views::cartesian_product(view, std::views::iota(0, 3))) {
const auto [s, i] = p;
std::cout << s << ", " << i << '\n';
}
return 0;
}
演示。
因此,这个答案回答了您关于
std::views::cartesian_product
应该如何工作的问题,并缩小了您寻找 std::istringstream
问题及其观点的范围。