userbb
userbb

Reputation: 1874

When is a constructor call a const-expr?

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

Answers (1)

Nir Friedman
Nir Friedman

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

Related Questions