如何将int unique_ptr转换为void unique_ptr?

4
假设我有一个长这样的函数:
void *func(){
    int *a = new int;
    *a = 1;

    void *b = a;
    return b;
}

在我的主函数中,我可以像这样使用它

int *test = reinterpret_cast<int *>(func());
std::cout << test[0] << std::endl;
delete test;

并且它将打印正确的结果。假设我想在我的函数中使用unique_ptr,那么它就变成了

std::unique_ptr<void> func(){
    std::unique_ptr<int> a(new int);
    *a = 1;

    std::unique_ptr<void> b = a; // does not compile
    return b;
}

它会抛出编译错误。

error: conversion from ‘std::unique_ptr<int>’ to non-scalar type ‘std::unique_ptr<void>’ requested

在这种情况下,我该怎么做才能让unique_ptr正常工作?


6
你认为 unique_ptr<void> 的语义是什么? - Brian Bi
2
另外,如果调用代码只是要将其强制转换回 int*,为什么要从函数返回 void* - Brian Bi
3
这没有意义。放弃void*部分,让你的类型明确无误。 - Baum mit Augen
1
就是不行。 - Lightness Races in Orbit
3
那么你最好通过unique_ptr<int>来管理所有权,并且在向传统API传递时将所管理的int*转换为void* - Brian Bi
显示剩余4条评论
1个回答

9

unique_ptr持有一个删除器(deleter),这个删除器在unique_ptr的生命周期结束时负责执行delete表达式(或delete[]表达式)来释放指针。

但是pvoid*时,表达式delete p是无效的。

unique_ptr的默认功能不支持void*。我不确定是否明确禁止使用unique_ptr<void>,但如果未被禁止,则尝试定义一个自定义删除器来完成此工作并不明智。

相反,应修复设计。

首先不要丢弃类型信息。


@skypjack:很不可能OP正在进行类型擦除。我认为那完全是错误的建议。正如答案中所述。 - Cheers and hth. - Alf
匿名的踩贴者:请解释一下你踩贴的原因,这样读者将来更容易忽略你的意见和投票。谢谢。 - Cheers and hth. - Alf
2
所以,unique_ptr的默认功能不支持void*类型[...]。但是如果没有明确禁止,那么试图定义一个自定义的删除器来完成这项工作并不明智。这就足够让人觉得不值得赞同。我同意问题可能源于设计问题,但这并不能证明给出了误导性的信息。我宁愿解释说void是被支持的,并展示它的工作原理,并说这种情况下不应使用它。通过说“它是一头野兽,迟早会咬到你”的方式,你没有为提问者和将来的读者提供正确的信息。以上是我的个人见解。 - skypjack
skypjack试图替我说话,这意味着他在任何事情上都可以被安全地忽略。无论如何,他所写的“void is supported”并不是真的。它仅仅没有被禁止,但是没有支持,特别是没有deleter。 - Cheers and hth. - Alf
关于“修复设计”语句。考虑从线路接收字节的情况。在头部之后,您有一个可变负载。可以通过void *转换轻松完成。我看不出任何不使用模板扩展的方法。 - Makketronix
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接