简体   繁体   中英

Why isn't this std::string_view a constant expression?

I'm relatively new to constexpr programming and am trying to do some basic manipulation of string_view objects in a constexpr context. In my case, all of the strings start as literals in my source code, so it seems like they should be constant expressions. I found that I can construct a constexpr string_view from a string literal without any issue.

However, if I try to invoke a constexpr function that takes a string_view argument with a string literal, then compilation fails. See the below example ( Compiler Explorer link ):

#include <string_view>

// this doesn't compile; the compiler complains that `sv` is not a constant-expression
constexpr bool foo(std::string_view sv) 
{
    constexpr auto it = sv.find('b'); 
    return it != sv.end();
}

// this compiles just fine, though
constexpr std::string_view bar("def");

int main()
{
    foo("abc");
}

gcc 8.3 provides the following error:

<source>: In function 'constexpr bool foo(std::string_view)':
<source>:5:32:   in 'constexpr' expansion of 'sv.std::basic_string_view<char>::find(((int)'b'), 0)'
<source>:5:36: error: 'sv' is not a constant expression
     constexpr auto it = sv.find('b');

Why is the string_view argument to foo() not treated as a constant expression?

A constexpr object's value is required to always be a compile-time constant. Since the function foo doesn't have any control over what arguments are passed to it, the parameter sv cannot be considered a constant expression (the caller may pass a non-constant-expression argument) and thus cannot be used to define it as a constexpr object.

The constexpr specifier can simply be removed from the definition of it , and then foo will compile and can even yield a constant expression (provided that the argument is a constant expression). (A constant expression is allowed to reference non- constexpr objects, although it is not allowed to call non- constexpr functions.)

By the way, the name it should not be used here since it is misleading. std::string_view::find returns an index, not an iterator.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM