'How to get std array size in a constant expression?
Consider this code:
#include <array>
#include <cstddef>
struct A {
std::array<std::size_t, 4> test;
void method() {
std::size_t duptest[test.size()] = {}; // error: variable-sized object may not be initialized
}
};
It fails under Clang with the error in the comment. I don't understand why this is considered a VLA, because test.size
is a constexpr
function. How do I stop duptest
from being interpreted as a VLA?
Solution 1:[1]
test
means this->test
, and evaluating this.size()
must first evaluate this->test
. But this
is not a constant expression so test.size()
is not a constant expression, even though std::array::size
is constexpr
and it doesn't use test
. Therefore this is a VLA and is nonstandard.
You might use std::tuple_size
.
size_t duptest[std::tuple_size<decltype(test)>()] = {};
Solution 2:[2]
The problem is that the expression test.size()
is equivalent to this->test.size()
but the this
object is more of a run-time construct. In particular, in standard C++ the size of an array must be a compile-time constant(aka constant expression) which the expression this->test.size()
is not. From expr.const#2:
An expression
e
is a core constant expression unless the evaluation ofe
, following the rules of the abstract machine, would evaluate one of the following expressions:
this
, except in a constexpr function or a constexpr constructor that is being evaluated as part ofe
;
Now in your example, this
appears inside the member function method
but the member function method
is neither constexpr nor it is being evaluated as part of the expression this->test.size()
.
Therefore this->test.size()
cannot be used to specify the size of the array since that expression is not a compile-time constant.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 |