在网络或C++20书籍中,我找不到一个例子来说明如何将std::ranges::istream_view的结果用于后续操作。我试图在编译器错误中使用的每一次后续操作都很难单独解决。
例如,我应该如何分割通过istream_view输入的惰性字符流?下面的代码不起作用,但希望能够传达我想要实现的目标:
#include <cstdlib>
#include <ranges>
#include <sstream>
#include <fmt/core.h>
auto main() -> int
{
std::istringstream data{"a,b"};
for (const auto& item:
std::views::istream<std::string>(data)
| std::views::split(",")
) {
fmt::print("{}\n", item);
}
return EXIT_SUCCESS;
}^我期望它在第一行上写"a",在第二行上写"b"。
GCC 12.2发出一条令人生畏的错误信息:
Could not execute the program
Compiler returned: 1
Compiler stderr
<source>: In function 'int main()':
<source>:11:5: error: no match for 'operator|' (operand types are 'std::ranges::basic_istream_view<std::__cxx11::basic_string<char>, char, std::char_traits<char> >' and 'std::ranges::views::__adaptor::_Partial<std::ranges::views::_Split, const char*>')
10 | std::views::istream<std::string>(data)
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| |
| std::ranges::basic_istream_view<std::__cxx11::basic_string<char>, char, std::char_traits<char> >
11 | | std::views::split(",")
| ^ ~~~~~~~~~~~~~~~~~~~~~~
| |
| std::ranges::views::__adaptor::_Partial<std::ranges::views::_Split, const char*>
In file included from <source>:2:
/opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/ranges:868:7: note: candidate: 'template<class _Lhs, class _Rhs> requires (derived_from<_Lhs, std::ranges::views::__adaptor::_RangeAdaptorClosure>) && (derived_from<_Rhs, std::ranges::views::__adaptor::_RangeAdaptorClosure>) constexpr auto std::ranges::views::__adaptor::operator|(_Lhs, _Rhs)'
868 | operator|(_Lhs __lhs, _Rhs __rhs)
| ^~~~~~~~
/opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/ranges:868:7: note: template argument deduction/substitution failed:
/opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/ranges:868:7: note: constraints not satisfied
In file included from /opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/ranges:37:
/opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/concepts: In substitution of 'template<class _Lhs, class _Rhs> requires (derived_from<_Lhs, std::ranges::views::__adaptor::_RangeAdaptorClosure>) && (derived_from<_Rhs, std::ranges::views::__adaptor::_RangeAdaptorClosure>) constexpr auto std::ranges::views::__adaptor::operator|(_Lhs, _Rhs) [with _Lhs = std::ranges::basic_istream_view<std::__cxx11::basic_string<char>, char, std::char_traits<char> >; _Rhs = std::ranges::views::__adaptor::_Partial<std::ranges::views::_Split, const char*>]':
<source>:11:28: required from here
/opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/concepts:67:13: required for the satisfaction of 'derived_from<_Lhs, std::ranges::views::__adaptor::_RangeAdaptorClosure>' [with _Lhs = std::ranges::basic_istream_view<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, char, std::char_traits<char> >]
/opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/concepts:67:28: note: 'std::ranges::views::__adaptor::_RangeAdaptorClosure' is not a base of 'std::ranges::basic_istream_view<std::__cxx11::basic_string<char>, char, std::char_traits<char> >'
67 | concept derived_from = __is_base_of(_Base, _Derived)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/ranges:859:7: note: candidate: 'template<class _Self, class _Range> requires (derived_from<typename std::remove_cvref<_Tp>::type, std::ranges::views::__adaptor::_RangeAdaptorClosure>) && (__adaptor_invocable<_Self, _Range>) constexpr auto std::ranges::views::__adaptor::operator|(_Range&&, _Self&&)'
859 | operator|(_Range&& __r, _Self&& __self)
| ^~~~~~~~
/opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/ranges:859:7: note: template argument deduction/substitution failed:
/opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/ranges:859:7: note: constraints not satisfied
/opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/ranges: In substitution of 'template<class _Self, class _Range> requires (derived_from<typename std::remove_cvref<_Tp>::type, std::ranges::views::__adaptor::_RangeAdaptorClosure>) && (__adaptor_invocable<_Self, _Range>) constexpr auto std::ranges::views::__adaptor::operator|(_Range&&, _Self&&) [with _Self = std::ranges::views::__adaptor::_Partial<std::ranges::views::_Split, const char*>; _Range = std::ranges::basic_istream_view<std::__cxx11::basic_string<char>, char, std::char_traits<char> >]':
<source>:11:28: required from here
/opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/ranges:831:13: required for the satisfaction of '__adaptor_invocable<_Self, _Range>' [with _Self = std::ranges::views::__adaptor::_Partial<std::ranges::views::_Split, const char*>; _Range = std::ranges::basic_istream_view<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, char, std::char_traits<char> >]
/opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/ranges:832:9: in requirements [with _Args = {std::ranges::basic_istream_view<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, char, std::char_traits<char> >}; _Adaptor = std::ranges::views::__adaptor::_Partial<std::ranges::views::_Split, const char*>]
/opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/ranges:832:44: note: the required expression 'declval<_Adaptor>()((declval<_Args>)()...)' is invalid
832 | = requires { std::declval<_Adaptor>()(declval<_Args>()...); };
| ~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~
cc1plus: note: set '-fconcepts-diagnostics-depth=' to at least 2 for more detail
In file included from /opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/streambuf:41,
from /opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/bits/streambuf_iterator.h:35,
from /opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/iterator:66,
from /opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/ranges:43:
/opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/bits/ios_base.h:87:3: note: candidate: 'constexpr std::_Ios_Fmtflags std::operator|(_Ios_Fmtflags, _Ios_Fmtflags)'
87 | operator|(_Ios_Fmtflags __a, _Ios_Fmtflags __b)
| ^~~~~~~~
/opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/bits/ios_base.h:87:27: note: no known conversion for argument 1 from 'std::ranges::basic_istream_view<std::__cxx11::basic_string<char>, char, std::char_traits<char> >' to 'std::_Ios_Fmtflags'
87 | operator|(_Ios_Fmtflags __a, _Ios_Fmtflags __b)
| ~~~~~~~~~~~~~~^~~
/opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/bits/ios_base.h:130:3: note: candidate: 'constexpr std::_Ios_Openmode std::operator|(_Ios_Openmode, _Ios_Openmode)'
130 | operator|(_Ios_Openmode __a, _Ios_Openmode __b)
| ^~~~~~~~
/opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/bits/ios_base.h:130:27: note: no known conversion for argument 1 from 'std::ranges::basic_istream_view<std::__cxx11::basic_string<char>, char, std::char_traits<char> >' to 'std::_Ios_Openmode'
130 | operator|(_Ios_Openmode __a, _Ios_Openmode __b)
| ~~~~~~~~~~~~~~^~~
/opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/bits/ios_base.h:170:3: note: candidate: 'constexpr std::_Ios_Iostate std::operator|(_Ios_Iostate, _Ios_Iostate)'
170 | operator|(_Ios_Iostate __a, _Ios_Iostate __b)
| ^~~~~~~~
/opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/bits/ios_base.h:170:26: note: no known conversion for argument 1 from 'std::ranges::basic_istream_view<std::__cxx11::basic_string<char>, char, std::char_traits<char> >' to 'std::_Ios_Iostate'
170 | operator|(_Ios_Iostate __a, _Ios_Iostate __b)
| ~~~~~~~~~~~~~^~~
In file included from /opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/span:42,
from /opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/ranges:45:
/opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/cstddef:132:3: note: candidate: 'constexpr std::byte std::operator|(byte, byte)'
132 | operator|(byte __l, byte __r) noexcept
| ^~~~~~~~
/opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/cstddef:132:18: note: no known conversion for argument 1 from 'std::ranges::basic_istream_view<std::__cxx11::basic_string<char>, char, std::char_traits<char> >' to 'std::byte'
132 | operator|(byte __l, byte __r) noexcept
| ~~~~~^~~发布于 2022-12-01 20:10:26
views::istream是一个输入范围。因此,您输入的任何适配器都必须在输入范围内工作。views::split需要转发或更好,这就是为什么您不能split一个istream。
但是也有一个views::lazy_split,它提供了一个稍微不同的接口,这样它确实可以在输入范围内工作(关于为什么我们需要forward+ split适配器,请参阅P2210中添加的上下文)。
但是,您有一个问题,即views::istream<string>是您尝试在逗号上拆分的一系列string。但这是不完全正确的,您想要的是一个范围的char,以便您最终得到一个范围的char。你的意思是views::istream<char>。
修好它,这行得通
auto main() -> int
{
std::istringstream data{"a,b"};
fmt::print("{}\n",
std::views::istream<char>(data)
| std::views::lazy_split(','));
}打印[['a'], ['b']]
https://stackoverflow.com/questions/74647598
复制相似问题