49

I can create constexpr std::array:

constexpr std::array<int,5> values {1,2,3,4,5};

It works fine. But I cannot create constexpr vector:

constexpr std::vector<int> vec = {1,2,3,4,5};

It gives me an error:

the type 'const std::vector<int>' of constexpr variable 'vec' is not literal constexpr std::vector<int> vec = {1,2,3,4,5};

Leo
  • 687
  • 1
  • 7
  • 14
  • 24
    Formally, that's because `vector` constructor is not declared `constexpr`. Why is it not so declared? Because `vector` constructor generally needs to allocate memory on the heap, which of course can only be done at run time. – Igor Tandetnik Oct 20 '15 at 16:36
  • @Igor Tandetnik so, there are no way to create constexpr vector? – Leo Oct 20 '15 at 16:42
  • 5
    No there is not. Why would you want to? It makes little sense to me. The whole point of `vector` is its ability to resize dynamically. If you don't need that, just use `std::array` or plain array. – Igor Tandetnik Oct 20 '15 at 16:46
  • 1
    @Igor Tandetnik. Actually, I am using `Qt` and there are nothing like `std::array` container, so I tried to use `QVector` and `QList` and it does not work. I don't want to mix `Qt` and `stl` containers. So, I guess now I have to – Leo Oct 20 '15 at 16:57
  • 3
    There are use cases, for example if you have a global array of pair where vector can consist of a limited (but variable) numbers known at compile time. – gast128 Oct 08 '18 at 10:00
  • @Leo `QVarLengthArray` same as std::array https://doc.qt.io/qt-6/qvarlengtharray.html –  Jun 15 '23 at 10:38

3 Answers3

79

There is a proposal to make std::vector constexpr: https://github.com/ldionne/wg21/blob/master/generated/p1004r1.pdf There is a whole talk about the upcoming C++20/23 changes: https://youtu.be/CRDNPwXDVp0?t=3080 So check again with C++20!

[edit]: constexpr std::vector has been approved for C++20! https://www.reddit.com/r/cpp/comments/au0c4x/201902_kona_iso_c_committee_trip_report_c20/

[edit 2019-10]: gcc trunk (with --std=c++2a flag) has started to implement constexpr new (a prerequisite for constexpr vector). See: https://youtu.be/FRTmkDiW5MM?t=372

[edit 2021-11]: both constexpr std::vector and constexpr std::basic_string are now implemented in gcc 12 ( https://en.cppreference.com/w/cpp/compiler_support )

user643011
  • 2,163
  • 3
  • 21
  • 38
35

For c++ version at least prior C++2a:

std::vector uses a dynamic memory allocation. Operator new can't be used in constexpr methods, thus std::vector will never be constexpr, constexpr constructor can't be declared for it. std::array doesn't use dynamic memory allocation, it is allocated in stack. It has no any problem with rules of creation constexpr objects and can be constexpr.

Роман Коптев
  • 1,555
  • 1
  • 13
  • 35
22

AFAIK The initlializer_list constructor of std::vector<> is not declared constexpr.

cdonat
  • 2,748
  • 16
  • 24
  • Actually, it is declared constexpr: c++20 draft: https://wg21.link/std20#lstlisting.22.-2632 and still in current draft sources: https://github.com/cplusplus/draft/blob/6091e264374349c12aa775cd66e5f062d9c7b9e4/source/containers.tex#L5706 it seems, it's just not yet implemented... – T S Sep 10 '21 at 09:36
  • 3
    It seems, the only compiler, that currently supports it is Visual Studio: https://en.cppreference.com/w/cpp/compiler_support#:~:text=constexpr%20std%3A%3Avector – T S Sep 10 '21 at 10:03