为什么这个 std::string_view 不是常量表达式?
Why isn't this std::string_view a constant expression?
我对 constexpr
编程比较陌生,正在尝试在 constexpr
上下文中对 string_view
对象进行一些基本操作。在我的例子中,所有字符串在我的源代码中都以文字开头,所以它们似乎应该是常量表达式。我发现我可以毫无问题地从字符串文字构造 constexpr string_view
。
但是,如果我尝试调用带有字符串文字的 string_view
参数的 constexpr
函数,则编译会失败。请参阅以下示例 (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 提供以下错误:
<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');
为什么 foo()
的 string_view
参数不被视为常量表达式?
constexpr
对象的值必须始终 是编译时常量。由于函数 foo
无法控制传递给它的参数,因此参数 sv
不能被视为常量表达式(调用者可以传递非常量表达式参数),因此不能用于将 it
定义为 constexpr
对象。
constexpr
说明符可以简单地从 it
的定义中删除,然后 foo
将编译并且甚至可以生成常量表达式(前提是参数是常量表达)。 (允许常量表达式引用非 constexpr
对象,但不允许调用非 constexpr
函数。)
顺便说一句,it
这个名字不应该在这里使用,因为它具有误导性。 std::string_view::find
returns 索引,不是迭代器。
我对 constexpr
编程比较陌生,正在尝试在 constexpr
上下文中对 string_view
对象进行一些基本操作。在我的例子中,所有字符串在我的源代码中都以文字开头,所以它们似乎应该是常量表达式。我发现我可以毫无问题地从字符串文字构造 constexpr string_view
。
但是,如果我尝试调用带有字符串文字的 string_view
参数的 constexpr
函数,则编译会失败。请参阅以下示例 (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 提供以下错误:
<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');
为什么 foo()
的 string_view
参数不被视为常量表达式?
constexpr
对象的值必须始终 是编译时常量。由于函数 foo
无法控制传递给它的参数,因此参数 sv
不能被视为常量表达式(调用者可以传递非常量表达式参数),因此不能用于将 it
定义为 constexpr
对象。
constexpr
说明符可以简单地从 it
的定义中删除,然后 foo
将编译并且甚至可以生成常量表达式(前提是参数是常量表达)。 (允许常量表达式引用非 constexpr
对象,但不允许调用非 constexpr
函数。)
顺便说一句,it
这个名字不应该在这里使用,因为它具有误导性。 std::string_view::find
returns 索引,不是迭代器。