假设我们有一些课程
struct Foo {
constexpr Foo(int& x) : x_(x) { x_++; }
constexpr ~Foo() noexcept { x_++; }
int& x_;
};
Run Code Online (Sandbox Code Playgroud)
在 C++20 中,g++-10 -std=c++20我们可以有这样的函数:
constexpr int do_foo_1() {
int x = 0;
Foo* p = new Foo(x);
delete p;
return x;
}
int main() {
static_assert(do_foo_1() == 2);
}
Run Code Online (Sandbox Code Playgroud)
让我们尝试将运算符new分为内存分配和就地构造。所以新函数看起来像这样:
constexpr int do_foo_2() {
int x = 0;
Foo* p = static_cast<Foo*>(::operator new(sizeof(Foo)));
p = ::new ((void*) p) Foo(x);
p->~Foo();
::operator delete(p);
return x;
}
Run Code Online (Sandbox Code Playgroud)
但是现在有两个错误:我们的内存分配new和placement new不是constexpr!
error: call to non-‘constexpr’ function ‘void* operator new(std::size_t)’
error: call to non-‘constexpr’ function ‘void* operator new(std::size_t, void*)’
Run Code Online (Sandbox Code Playgroud)
因此,让我们尝试解决这些错误。随着<memory>我们能有这样的代码:
error: call to non-‘constexpr’ function ‘void* operator new(std::size_t)’
error: call to non-‘constexpr’ function ‘void* operator new(std::size_t, void*)’
Run Code Online (Sandbox Code Playgroud)
题
我的用法和标准库中这些运算符的用法有什么区别?引擎盖内std::construct_at和std::allocator<Foo>::allocate引擎盖下不是发生同样的事情吗?
笔记
我试图通过简单地复制它的实现来复制 std::construct_at<stl_construct.h>但我得到了同样的错误:
error: ‘constexpr decltype (...) my_construct_at(_Tp*, _Args&& ...) [...]’ called in a constant expression
error: call to non-‘constexpr’ function ‘void* operator new(std::size_t, void*)
Run Code Online (Sandbox Code Playgroud)
我的用法和标准库中这些运算符的用法有什么区别?
您的用法未调用std::allocator<T>::allocate或std::construct_at。
这些特定功能 - 以及其他一些功能 - 被特别授予正常规则的例外情况:
为了确定表达式E是否是核心常量表达式,对
std?::?allocator<T>[allocator.members] 中定义的成员函数的调用的评估 ,其中T是文字类型,不会取消E作为核心常量表达式的资格,即使对此类调用的实际评估将无法满足核心常量表达式的要求。类似地,为一个呼叫的评价std?::?destroy_at,std?::?ranges?::?destroy_at,std?::?construct_at,或std ::范围:: construct_at不资格????Ë从一个核心常量表达式除非:[...]
至于普通new表达式,在不断评估期间,它从不调用::operator new:
在常量表达式的求值过程中,总是省略对分配函数的调用。
| 归档时间: |
|
| 查看次数: |
131 次 |
| 最近记录: |