Search code examples
c++17gcc-warningstring-view

std::string_view issues on GCC8


I have some simple code using std::string_view which works great in gcc10, but not in gcc8.

std::string_view was added to C++17 in GCC 7, so it should be possible to use this.

#include <string_view>
using sv = std::string_view;

sv ParseScheme(const sv& url)
{
    sv pattern = "://";
    if (auto found = url.find(pattern); found != sv::npos)
    {
        return sv(url.begin(), url.begin() + found);
    }
    return sv();
}

Compiling gives me:

$ g++ main.cpp --std=c++17 -Werror
main.cpp: In function 'sv ParseScheme(const sv&)':
main.cpp:9:44: error: invalid conversion from
    'std::basic_string_view<char>::const_iterator' {aka 'const char*'} to 
    'std::basic_string_view<char>::size_type' {aka 'long unsigned int'} [-fpermissive]
         return sv(url.begin(), url.begin() + found);
                                ~~~~~~~~~~~~^~~~~~~
In file included from main.cpp:1:
/usr/include/c++/8/string_view:105:56: note:   initializing argument 2 of 
    'constexpr std::basic_string_view<_CharT, _Traits>::basic_string_view(
        const _CharT*, std::basic_string_view<_CharT, _Traits>::size_type
    ) [with 
        _CharT = char; 
        _Traits = std::char_traits<char>; 
        std::basic_string_view<_CharT, _Traits>::size_type = long unsigned int
    ]'
       basic_string_view(const _CharT* __str, size_type __len) noexcept
                                              ~~~~~~~~~~^~~~~

Is there something I'm actually doing wrong, or are string_views in gcc8 just broken?

I could use -fpermissive to ignore the issue, but we compile with -Werror, so an -fpermissive warning will fail the build anyways.


Solution

  • The string_view(Iterator,Iterator) constructor used here was added in C++20. that's why it doesn't work in gcc8.

    An alternative is to use the string_view(const char*, size_type) constructor availalbe in C++17:

    #include <string_view>
    using sv = std::string_view;
    
    sv ParseScheme(const sv& url)
    {
        sv pattern = "://";
        if (auto found = url.find(pattern); found != sv::npos)
        {
            return sv(url.data() + found, url.size() - found);
        }
        return sv();
    }