以下代码可以正常编译:
#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
!
这是未定义的行为吗?还是新放置的位置不算作修改?
我修改了*a
的值const。据我了解,这是不允许的:
通过非常量访问路径修改const对象,并 通过非易失性glvalue结果引用易失性对象 处于不确定状态。
答案 0 :(得分:4)
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
的伪dtor是微不足道的,因此甚至不需要在它之上构造一个新的伪dtor就被调用。
答案 1 :(得分:0)
const int* a
指定a
所指向的内存插槽中包含的值是常量,而不是指针本身。
#include <memory>
int main()
{
const int * a = new int;
a = nullptr; // Compile fine
*a = 1; // Won't compile
return 0;
}
您希望代码的行为类似于:
#include <memory>
int main()
{
int* const a = new int;
a = nullptr; // Won't compile
*a = 1; // Compile fine
return 0;
}