'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
eis 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 |
