为什么这个 std::string_view 不是常量表达式?

Jas*_*n R 5 c++ constexpr c++17

我对constexpr编程比较陌生,正在尝试string_viewconstexpr上下文中对对象进行一些基本操作。就我而言,所有字符串在我的源代码中都以文字开头,因此它们似乎应该是常量表达式。我发现我可以constexpr string_view从字符串文字构造 a ,没有任何问题。

但是,如果我尝试调用一个采用字符串文字作为参数的constexpr函数,则编译会失败。string_view请参阅以下示例(编译器资源管理器链接):

#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");
}
Run Code Online (Sandbox Code Playgroud)

gcc 8.3 提供以下错误:

<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');
Run Code Online (Sandbox Code Playgroud)

为什么string_view参数 tofoo()不被视为常量表达式?

Bri*_*ian 5

对象constexpr的值必须始终是编译时常量。由于该函数foo无法控制传递给它的参数,因此该参数sv不能被视为常量表达式(调用者可以传递非常量表达式参数),因此不能用于定义为it对象constexpr

constexpr可以简单地从 的定义中删除说明符,it然后foo进行编译,甚至可以生成常量表达式(前提是参数是常量表达式)。(常量表达式允许引用非constexpr对象,但不允许调用非constexpr函数。)

it顺便说一下,这里不应该使用这个名称,因为它会产生误导。std::string_view::find返回一个索引,而不是迭代器。