为什么用成员数组调用constexpr函数不是常量表达式? [英] Why is calling a constexpr function with a member array not a constant expression?
问题描述
我具有以下帮助函数:
template<typename T, std::size_t N>
constexpr std::size_t Length(const T(&)[N]) {
return N;
}
返回静态数组的长度。在过去,这一直有效,但是当我这样做时:
Which returns the length of a static array. In the past this always has worked but when I do this:
struct Foo
{
unsigned int temp1[3];
void Bar()
{
constexpr std::size_t t = Length(temp1); // Error here
}
};
使用MSVS 2017时出现错误:
I get an error when using MSVS 2017:
error C2131: expression did not evaluate to a constant
note: failure was caused by a read of a variable outside its lifetime
note: see usage of 'this'
我希望有人可以阐明我做错了。
I was hoping someone can shed light on what I'm doing wrong.
推荐答案
MSVC是正确的。 Length(temp1)
不是常量表达式。来自 [expr.const] p2
MSVC is correct. Length(temp1)
is not a constant expression. From [expr.const]p2
表达式 e 是一个核心常量表达式,除非按照抽象机的规则对 e 的求值将对其中一个求值。以下表达式:
An expression e is a core constant expression unless the evaluation of e, following the rules of the abstract machine, would evaluate one of the following expressions:
-
this
,但在constexpr函数或constexpr构造函数中被评估为 e 的一部分;
this
, except in a constexpr function or a constexpr constructor that is being evaluated as part of e;
temp1
隐式评估 this
(因为您指的是 this-> temp1
),所以您不会有一个常数表达式gcc和clang接受它是因为它们支持VLA作为扩展(尝试使用 -Werror = vla
或 -pedantic-errors
)。
temp1
evaluates this
implicitly (because you are referring to this->temp1
), and so you don't have a constant expression. gcc and clang accept it because they support VLAs as an extension (try compiling with -Werror=vla
or -pedantic-errors
).
为什么不允许这样做?好了,您可以访问基础元素并可能对其进行修改。如果您要处理 constexpr
数组或要作为常量表达式求值的数组,这是完全可以的,但是如果不是这样,则可能无法拥有常量表达式,因为您将要处理在运行时设置的值。
Why isn't this allowed? Well, you could access the underlying elements and potentially modify them. This is completely fine if you are dealing with a constexpr
array or an array that is being evaluated as a constant expression, but if you are not, then you cannot possibly have a constant expression as you will be manipulating values that are set at run time.
这篇关于为什么用成员数组调用constexpr函数不是常量表达式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!