gpt4 book ai didi

c++ - 为什么 std::istream_iterator< std::string_view > 无法编译?

转载 作者:行者123 更新时间:2023-12-02 01:34:01 24 4
gpt4 key购买 nike

为什么 GCC 和 Clang 无法编译下面的代码片段( link )?我想返回一个 std::string_view vector ,但显然无法从 stringstream 中提取 string_view

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


[[ nodiscard ]] std::vector< std::string_view >
tokenize( const std::string_view inputStr, const size_t expectedTokenCount )
{
std::vector< std::string_view > foundTokens { };

if ( inputStr.empty( ) ) [[ unlikely ]]
{
return foundTokens;
}

std::stringstream ss;
ss << inputStr;

foundTokens.reserve( expectedTokenCount );

std::copy( std::istream_iterator< std::string_view >{ ss }, // does not compile
std::istream_iterator< std::string_view >{ },
std::back_inserter( foundTokens ) );

return foundTokens;
}

int main( )
{
using std::string_view_literals::operator""sv;
constexpr auto text { "Today is a nice day."sv };

const auto tokens { tokenize( text, 4 ) };

std::cout << tokens.size( ) << '\n';
std::ranges::copy( tokens, std::ostream_iterator< std::string_view >{ std::cout, "\n" } );
}

请注意,用 string 替换 string_view 的选定实例可以让代码编译。

最佳答案

因为没有运算符>>std::stringstreamstd::string_view (并且 std::istream_iterator 需要此运算符)。

@tkausl在评论中指出, >> 是不可能的致力于std::string_view因为尚不清楚谁将拥有 std::string_view 所指向的内存。 .

就您的程序而言,ss << inputStr复制 inputStr 中的字符进入ss ,当 ss超出范围,其内存将被释放。


这里是使用 C++20 的 std::ranges::views::split 的可能实现而不是std::stringstream 。它只支持单个空格作为分隔符。

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


[[ nodiscard ]] std::vector< std::string_view >
tokenize( const std::string_view inputStr, const size_t expectedTokenCount )
{
constexpr std::string_view delim { " " };

std::vector< std::string_view > foundTokens { };

if ( inputStr.empty( ) ) [[ unlikely ]]
{
return foundTokens;
}

foundTokens.reserve( expectedTokenCount );
for ( const auto token : std::views::split( inputStr, delim ) )
{
foundTokens.emplace_back( token.begin( ), token.end( ) );
}

return foundTokens;
}

int main( )
{
using std::string_view_literals::operator""sv;
constexpr auto text { "Today is a nice day."sv };

const auto tokens { tokenize( text, 4 ) };

std::cout << tokens.size( ) << '\n';
std::ranges::copy( tokens, std::ostream_iterator< std::string_view >{ std::cout, "\n" } );
}

这适用于 gcc 12.1(使用 -std=c++20 编译),但不适用于 clang 14.0.0,因为 clang 尚未实现 P2210还没有。

关于c++ - 为什么 std::istream_iterator< std::string_view > 无法编译?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72827897/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com