下面的代码可以正常编译:
#include <iostream>
#include <memory>
int main()
{
const int * a = new int(5);
std::cout << *a << std::endl; // Prints 5
// *a = 5; // Compiler error.
using at = std::allocator_traits<typename std::allocator<int>>;
auto alloc = std::allocator<int>();
at::construct(alloc, a);
std::cout << *a << std::endl; // Prints 0
}
在 libstdc++ 的背后
::new((void*)a) int;
但是 a
是 const
!
这是未定义的行为吗?或者 placement new 不算修改?
我修改了*a
的值,是const。据我了解,这是不允许的:
Modifying a const object through a non-const access path and referring to a volatile object through a non-volatile glvalue results in undefined behavior.
最佳答案
TL;DR:在 C++2a 之前都很好,此后 std::allocator_traits<std::allocator<int>>::construct()
将对传递的指针要求更高。
嗯,std::allocator_traits::construct()
uses static_cast<void*>
since it was introduced ,除非分配器提供它。
同时 std::allocator::construct()
在 C++17 中已弃用,并将在 C++2a 中删除,它始终使用 C 风格的转换。
因此,它在 C++2a 之前在语法上是有效的。
因为指向的对象本身不是 const
,只有通过具有该限定符才能访问的指针,丢弃 const
并且修改是完全合法的。
作为 int
的伪驱动程序是微不足道的,在它上面构建一个新的之前不调用它甚至都没有关系。
关于c++ - std::allocator_traits::construct with const 指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56942404/