在 C++ 中使用 std::views::split 填充 std::vector 存在困难

Saj*_*log 1 c++ split c++20 std-ranges

std::vector我在尝试用 C++ 中的结果填充 a 时遇到问题std::views::split。具体来说,我可以成功地std::string从 的项构造 a std::ranges::split_view(如下面代码的第一个循环所示),但在尝试使用迭代器std::vector直接创建 a 时遇到困难。

// requires /std:c++20 or later
#include <ranges>
#include <iostream>
#include <vector>

int main()
{
    std::string rg{ "1, 2, 3, 1, 2, 3, 4, 5, 6 "};

    // Successful construction of std::string from std::ranges::split_view
    for (const auto& subrange : rg | std::views::split('3'))
    {
        std::string value(subrange.begin(), subrange.end());
        std::cout << value << '\n';
    }

    // Issue arises here when attempting to create std::vector
    auto parts = rg | std::views::split('3');
    auto asVector = std::vector<std::string>(parts.begin(), parts.end());

    // The following loop results in a compilation error
    for (const auto& subrange : asVector)
    {
        std::string value(subrange.begin(), subrange.end());
        std::cout << value << '\n';
    }
}
Run Code Online (Sandbox Code Playgroud)

编译错误:

Error   C2665   'std::basic_string<char,std::char_traits<char>,std::allocator<char>>::basic_string': no overloaded function could convert all the argument types    
splitView   C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.38.33030\include\xutility    241
Run Code Online (Sandbox Code Playgroud)

我感谢任何能帮助我解决此问题的见解或解决方案。

康桓瑋*_*康桓瑋 6

的值类型rg | std::views::split('3')subrange<string::iterator, string::iterator>, 且string无法通过其构造,即为is_constructible<string, subrange<string::iterator, string::iterator>false,因此编译失败。

理想的方法是使用 C++23 ranges::to

auto asVector = std::ranges::to<std::vector<std::string>>(parts);
Run Code Online (Sandbox Code Playgroud)

它是递归应用的,因此string首先从subrangevia (嵌套)构造ranges::to,然后调用其范围构造函数string(from_range_t, R&&),然后vector随后构造 。

在C++20中你仍然需要手动将原始的转换subrangestd::string

auto parts = rg | std::views::split('3') 
                | std::views::transform([](auto r) {
                    return std::string(r.data(), r.size());
                  });
auto asVector = std::vector(parts.begin(), parts.end());
Run Code Online (Sandbox Code Playgroud)