32
votes

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};

3
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
@Igor Tandetnik so, there are no way to create constexpr vector?Leo
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
@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 toLeo
There are use cases, for example if you have a global array of pair<enum, vector> where vector can consist of a limited (but variable) numbers known at compile time.gast128

3 Answers

20
votes

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

52
votes

std::vector is not constexpr. 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

27
votes

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.