Search code examples
c++constant-expression

Why initialization of constexpr variable from non constexpr variable succeeds in case of class


I have learnt about constexpr variables in c++ and read that int i =0; constexpr int j = i; fails because i is not a constant expression which makes sense. But then when I did the same with a variable of a class, it worked.

struct C{};
int main()
{
    int i = 0; //i is not a constant expression as expected 
    //constexpr int j = i; //this fails AS EXPECTED

    C c; 
    constexpr C d = c; //WHY DOESN'T THIS FAIL?? 
}

As you can see, constexpr C d = c; compiles without any problem unlike constexpr int j = i; even though c is also not a constant expression.

I want to know the reason behind this.


Solution

  • I want to know the reason behind this.

    Because the class C has an implicit constexpr copy constructor constexpr C::C(const C&) that can be used in constexpr context like this.

    Basically the initialization constexpr C d = c; is a constexpr context and the constexpr ctors are designed exactly for these purposes.


    You can also see this by looking at the generated code at cppinsights:

    struct C
    {
      // inline constexpr C() noexcept = default;
      // inline constexpr C(const C &) noexcept = default;
    };
    
    

    As we can see in the above generated code, C has implicitly declared constexpr constructors that can be used in constexpr contexts.


    From constexpr:

    A constexpr variable must satisfy the following requirements:

    • ...
    • the full-expression of its initialization, including all implicit conversions, constructors calls, etc, must be a constant expression