Reputation: 11706
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?
Upvotes: 5
Views: 2886
Reputation: 119219
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.
Upvotes: 6