Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How is std::vector able to be constexpr without constexpr std::uninitialized_copy?

I am implementing my own container and I was trying to make it as much constexpr friendly as possible.

In the process I found out that std::uninitialized_copy is not constexpr and therefore I can't implement copy assignment using the standard algorithms.

However, std::vector is constexpr friendly:

constexpr auto f() {
    std::vector<int> v = {1, 2, 3};
    return v.size();
}

static_assert(f() == 3);

I can't achieve this when I replace std::vector by my own container. I get the error:

... error: call to non-‘constexpr’ function ‘_ForwardIterator std::uninitialized_copy(_InputIterator, ...

I wonder how the standard library (e.g. stdlib) can implement that. Does it use a secret implementation of uninitialized_copy that is constexpr? Is a constexpr uninitalized_copy implementable at all?

I guess the challenge is to have constexpr addressof and constexpr construct_at. Is there an implementation that I can fallback into?

like image 233
alfC Avatar asked Feb 07 '26 13:02

alfC


1 Answers

std::vector doesn't use std::uninitialized_copy. It calls std::allocator_traits::construct to perform copy construction. The latter defaults to calling std::construct_at, which is handled specially during constant evaluation ([expr.const]/6).

In practice, compilers treats std::construct_at specially, so that it can use placement new during constant evaluation.

  • MSVC uses a secret attribute to define the placement operator new and to call it inside std::construct_at. (Well, it's not that secret.)
  • Clang permits placement new during constant evaluation when the enclosing function is within namespace std.
  • GCC and EDG permit placement new when the enclosing function template is named std::construct_at.
like image 142
cpplearner Avatar answered Feb 09 '26 09:02

cpplearner



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!