c++c++20constexpr

`constexpr vector` still fails, while there's stated to be supported in cppreference


On https://en.cppreference.com/w/cpp/compiler_support, constexpr vector is stated to be supported. enter image description here

But when I wrote

#include <vector>

constexpr std::vector<int> vec{2, 3, 3, 3};
int main()
{
}

and compiles it using -std=gnu++2b flag, it still triggers a error

In file included from /usr/include/c++/12/vector:61,
                 from test.cpp:1:
/usr/include/c++/12/bits/allocator.h:182:50: error: ‘std::vector<int>(std::initializer_list<int>{((const int*)(& const int [4]{2, 3, 3, 3})), 4}, std::allocator<int>())’ is not a constant expression because it refers to a result of ‘operator new’
  182 |           return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp)));
      |                                    ~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~

I don't understand why, can someone help me?

My gcc version gcc version 12.1.0 (Ubuntu 12.1.0-2ubuntu1~22.04)

and __cpp_constexpr == 202110L


Solution

  • std::vector being constexpr-friendly means that it can be used inside a constant expression evaluation. It does not mean that a variable of that type can be declared with constexpr specifier. (Talking about constexpr std::vector in that context is maybe a bit misleading.)

    Because std::vector uses dynamic allocation, it still must be destroyed during the evaluation of the constant expression, which is not the case in the initialization of a variable of that type.

    What is allowed now is e.g.:

    constexpr int some_calculation(int input) {
        std::vector<int> vec;
        // some complicated algorithm using `input`, using `vec` to store e.g. intermediate results
        return /* the result */;
    }
    
    constexpr int constant_value = some_calculation(42);