std::unique_ptr<void> 不被 GCC 4.9.0 接受
std::unique_ptr<void> not accepted by gcc 4.9.0
因此gcc 4.9.0
实现了一个类型不是void
的static_assert
离子以正确符合标准。这很好,都是为了符合标准。
我有一个变体类型,将数据存储在std::unique_ptr<void>
下,现在不起作用。简单的修复方法是将其更改为std::shared_ptr<void>
,并立即编译。更好的修复方法是提供deleter函函数。
下面是修复unique_ptr
的安全方法吗?这是否会在某些多态类型中表现出未定义的行为?
#include <memory>
#include <iostream>
template<typename T>
void Deleter(void * p) {
delete reinterpret_cast<T*>(p);
}
int main() {
const std::unique_ptr<void, void(*)(void*)> v(new int(199), Deleter<int>);
std::cout << *reinterpret_cast<int*>(v.get()) << std::endl;
return 0;
}
这是否会在某些多态类型中表现出未定义的行为?
如果您使用unique_ptr<void, void(*)(void*)>(new X(...), Deleter<X>)
,那么对于任何X
都是正确的,因为删除器使用了正确的对象动态类型。
如果Base
没有虚拟析构函数,或者Base
子对象与包含它的Derived
对象不在同一个地址,那么unique_ptr<void, void(*)(void*)>(new Derived(...), Deleter<Base>)
将具有未定义的行为(对于多态和非多态类型)。
但是,您应该在两个地方都使用static_cast
而不是reinterpret_cast
。你应该选择在特定情况下使用最弱的cast, reinterpret_cast
是一个大锤。
为了使代码更不容易出错,我将编写一个辅助函数,以便您只命名一次类型,例如:
template<typename T, typename... Args>
std::unique_ptr<void, void(*)(void*)>
make_unique_void_ptr(Args&&... args)
{
using Ptr = std::unique_ptr<void, void(*)(void*)>;
return Ptr{ new T(std::forward<Args>(args)...), Deleter<T> };
}
相关文章:
- 构造函数采用 Base&不被调用
- 叮叮当当:什么可能导致NOLINT评论不被尊重?
- 为什么"using System;"不被视为不良做法?
- 为什么矢量子项不被修改?
- 为什么 GCC 不能假设 std::vector::size 在这个循环中不会改变?
- 野牛/yacc 解析器在不被空格分隔时跳过 grammer - "unexpected $end"
- 为什么数组中对象的析构函数在被另一个对象替换时不被调用?
- 为什么MSVC(Visual C++)需要单独的dllimport和dllexport属性,而gcc不需要
- 为什么 GCC 不优化删除 C++ 中的空指针?
- GCC 不支持新表达式中的大括号省略号
- 'cmake'不被识别为内部或外部命令 - 北极星
- l值引用对象上的Constexpr成员函数:Clang和gcc不同意
- 除了说明符神秘地破坏编译(Clang,GCC不同意)
- 为什么注入的类名有时不被视为类模板中的模板名?
- Const Int 宣布与 stoi 不被视为 const
- 如何保护 MSI 不被修改
- 在模板实例化期间,文本值不被视为常量表达式
- C++函数到指针的隐式转换:哪个编译器是正确的?Clang和GCC不同意
- 动态对齐的多维数组不被 GCC 编译器视为对齐
- std::unique_ptr<void> 不被 GCC 4.9.0 接受