如果没有 constexpr std::uninitialized_copy,std::vector 如何能够成为 constexpr?

alf*_*lfC 2 c++ initialization std constexpr

我正在实现我自己的容器,并且我试图使其尽可能对 constexpr 友好。

\n

在这个过程中,我发现这std::uninitialized_copy不是 constexpr,因此我无法使用标准算法实现复制分配。

\n

然而, constexprstd::vector 是否友好:

\n
constexpr auto f() {\n    std::vector<int> v = {1, 2, 3};\n    return v.size();\n}\n\nstatic_assert(f() == 3);\n
Run Code Online (Sandbox Code Playgroud)\n

当我替换为我自己的容器时,我无法实现此目的std::vector。\n我收到错误:

\n
... error: call to non-\xe2\x80\x98constexpr\xe2\x80\x99 function \xe2\x80\x98_ForwardIterator std::uninitialized_copy(_InputIterator, ...\n
Run Code Online (Sandbox Code Playgroud)\n

我想知道标准库(例如 stdlib)如何实现这一点。\n它是否使用uninitialized_copyconstexpr 的秘密实现?\nconstexpr uninitalized_copy 是否可以实现?

\n

我想挑战在于拥有constexpr addressofconstexpr construct_at。\n是否有一个我可以回退的实现?

\n

cpp*_*ner 9

std::vector不使用std::uninitialized_copy. 它要求std::allocator_traits::construct执行复制构造。后者默认调用,它在常量求值 ( [expr.const]/6std::construct_at )期间进行特殊处理。

在实践中,编译器会进行std::construct_at特殊处理,以便在不断求值期间可以使用placement new。

  • MSVC 使用秘密属性来定义放置operator new并在内部调用它std::construct_at。(好吧,这并不是那么秘密。)
  • 当封闭函数位于命名空间内时,Clang 允许在持续求值期间放置 new std
  • GCC 和 EDG 允许在命名封闭函数模板时放置 new std::construct_at