Reputation: 1874
When is the constructor call a const-expr and when is it not? In this links question
Are these vector definitions "constant initialization"?
The constructor is not a const-expr and that's why the vector
is not const initialized. Also could someone explain the answer from that question with more details ?
Upvotes: 4
Views: 318
Reputation: 17704
Are you asking when can the result of a construction be used in a context that requires a constant expression? E.g.
class A {
constexpr A(...) { ... };
constexpr int get() { ... };
...
}
constexpr A a(...);
std::array<double, a.get()> x{};
In other words, when is this legal? std::array
's second template parameter must be a constant expression (http://en.cppreference.com/w/cpp/language/constant_expression) integer, get
is constexpr
, so this will be ok if a
is constexpr. In turn, A's constructor is constexpr (meaning it has to follow these rules: http://en.cppreference.com/w/cpp/language/constexpr). That means that a
can be marked a constant expression (note that you still need to explicitly request it via ''constexpr'' when you declare the variable) if all the arguments you pass the constructor are constant expressions, basically either literals or other constexpr
variables.
Working example:
struct A {
constexpr A(int x) : m_x(x) {};
constexpr int get() { return m_x; }
int m_x;
};
int main(int, char**)
{
constexpr int x = 5;
constexpr A a(x);
std::array<double, a.get()> y;
return 0;
}
Note that if you change the declaration of x
from constexpr
to const
, it will not compile. Similarly, if you don't declare A's constructor constexpr
, it will also not compile, because that will mean that a
is not a constant expression, which means that a.get()
is not a constant expression. As you can see, it all works very transitively, which makes sense: if you want to compute something at compile time that depends on other things, every single step of the computation along the way must also be doable at compile time. That means that functions (including constructors) and variables must both meet the requirements for being constexpr
as outlined in the link above, and they must be explicitly marked so (excepting literals like 5
which are always constexpr
).
Upvotes: 1