constexpr string_view length

Anyone know why this doesn't compile in C++17?

The compiler is telling me that my that I'm calling a non-constexpr length() function.
call to non-constexpr function 'static std::size_t std::char_traits<char>::length(const char_type*)'

but the documentation says string_view.length() should be constexpr in C++17, so what is the issue?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <string>
#include <string_view>

constexpr std::string_view foobar()
{
    return std::string_view("Hello world");
}

template <size_t n>
constexpr void foobar_checker() {}

constexpr void verify_foobar()
{
    foobar_checker<foobar().length()>();
}

int main()
{
    std::cout << foobar() << '\n';
}


g++ -Wall -std=c++17 main.cpp -o main
main.cpp: In function 'constexpr void verify_foobar()':
main.cpp:15:39: error: no matching function for call to 'foobar_checker<foobar().std::basic_string_view<char, std::char_traits<char> >::length()>()'
     foobar_checker<foobar().length()>();
                                       ^
main.cpp:11:16: note: candidate: template<long long unsigned int n> constexpr void foobar_checker()
 constexpr void foobar_checker() {}
                ^~~~~~~~~~~~~~
main.cpp:11:16: note:   template argument deduction/substitution failed:
In file included from c:\mingw\include\c++\7.1.0\bits\basic_string.h:48:0,
                 from c:\mingw\include\c++\7.1.0\string:52,
                 from c:\mingw\include\c++\7.1.0\bits\locale_classes.h:40,
                 from c:\mingw\include\c++\7.1.0\bits\ios_base.h:41,
                 from c:\mingw\include\c++\7.1.0\ios:42,
                 from c:\mingw\include\c++\7.1.0\ostream:38,
                 from c:\mingw\include\c++\7.1.0\iostream:39,
                 from main.cpp:1:
main.cpp:15:27:   in constexpr expansion of 'foobar()'
main.cpp:15:36:   in constexpr expansion of 'std::basic_string_view<char>(((const char*)"Hello world"))'
c:\mingw\include\c++\7.1.0\string_view:100:58: error: call to non-constexpr function 'static std::size_t std::char_traits<char>::length(const char_type*)'
       : _M_len{__str == nullptr ? 0 : traits_type::length(__str)},
                                       ~~~~~~~~~~~~~~~~~~~^~~~~~~
main.cpp:15:39: note: in template argument for type 'long long unsigned int'
     foobar_checker<foobar().length()>();
                                       ^


https://en.cppreference.com/w/cpp/string/basic_string_view/size
https://en.cppreference.com/w/cpp/string/char_traits/length

Edit: Apparantly other people have had similar issues?
https://stackoverflow.com/questions/56484834/constexpr-stdstring-viewfind-last-of-doesnt-work-on-clang-8-with-libstdc
(no answer)
Last edited on
Appears to be a bug.

1
2
3
4
5
6
7
8
9
10
11
12
13
template <std::size_t>
constexpr void foobar_checker() {}

constexpr void verify_foobar()
{
    constexpr auto sz = foobar().length() ; // fine
    foobar_checker<sz>() ;

    constexpr auto view = foobar() ; 
    foobar_checker< view.length() >(); // fine
    
    // foobar_checker< foobar().length() >(); // *** error
}

http://coliru.stacked-crooked.com/a/01db64ca8a191d9a
Thanks for confirming, I should probably update my MinGW...

Edit: Oh I see, it's a bug even with non-MinGW g++.
Last edited on
foobar_checker< foobar().length() >(); compiles cleanly on MinGW with
mingw64/mingw-w64-x86_64-gcc 9.1.0-3
mingw64/mingw-w64-x86_64-clang 8.0.1-3

(and also on Visual Studio 2019)
Topic archived. No new replies allowed.