error: no matching function for call to ‘take_view(std::stringstream&, long unsigned int)’

error: no matching function for call to ‘take_view(std::stringstream&, long unsigned int)’

我想从 std::stringstream 中提取最多 N + 1 个字符串。

目前,我有以下代码(需要修复):

#include <iostream>
#include <iomanip>
#include <sstream>
#include <string>
#include <string_view>
#include <vector>
#include <iterator>
#include <ranges>
#include <algorithm>


int main( )
{
    const std::string_view sv { "   @a hgs  -- " };
    const size_t expectedTokenCount { 4 };

    std::stringstream ss;
    ss << sv;

    std::vector< std::string > foundTokens;
    foundTokens.reserve( expectedTokenCount + 1 );

    std::ranges::for_each( std::ranges::take_view { ss, expectedTokenCount + 1 }, [ &foundTokens ]( const std::string& token )
                                                                                  {
                                                                                    std::back_inserter( foundTokens );
                                                                                  } );

    if ( foundTokens.size( ) == expectedTokenCount )
    {
        // do something
    }

    for ( const auto& elem : foundTokens )
    {
        std::cout << std::quoted( elem ) << '\n';
    }
}

我该如何解决?另外,我应该如何使用 back_inserter 将提取的字符串 push_back 转换为 foundTokens?

请注意,以下别名有效:

namespace views = std::views;
namespace rng = std::ranges;

这里有一些问题和奇怪之处。首先:

std::ranges::take_view { ss, expectedTokenCount + 1 }

常规使用std::views API:

ss | views::take(expectedTokenCount + 1)

这里更明显的问题是 ss 不是视图或范围。您需要创建一个正确的视图:

auto tokens = views::istream<std::string>(ss) | views::take(expectedTokenCount + 1);

现在是另一个问题:

std::back_inserter( foundTokens );

这是一个no-op。它为容器创建一个 back-inserter,它是一个迭代器,其迭代导致 push_back 被调用,但随后不使用它。

虽然在 C++20 中从范围或视图创建向量的情况很差,但这是一种方法:

rng::copy(tokens, std::back_inserter(foundTokens));

将所有这些放在一起,您可以看到一个 live example,但请注意,它可能不是 100% 正确的——它目前使用 GCC 编译,而不是使用 Clang。

如下所述,如果标记之间存在一致的分隔符,您还可以使用 views::split 直接拆分源字符串:

std::string_view delim = " ";
auto tokens = views::split(sv, delim);

但是,如果您的标准库没有实现 this defect report,您可能 运行 会遇到麻烦 this defect report