为什么const void*没有std::free重载函数?

7
我使用一个返回动态分配的const char*的extern C函数。

我想使用unique_ptr<const char, decltype(std::free)>来管理它。

但是没有std::free(const void*)重载,所以我得到了invalid conversion from 'const void*' to 'void*',必须使用const_cast<char*>()

这只是标准库的缺陷,还是背后有其他原因?


3
@ForceBru,这个指针不是“const”,它指向的是“const”内存。 - sad1raf
2
@ForceBru:然而delete const指针是可以的。 - Fred Larson
3
如果函数返回了需要释放的内容,那么它就不应该是一个指向常量的指针。据我所知,free有完全权利修改它释放的内存,这是函数的问题,而不是free的问题。我不知道动态分配内存无法被修改的情况(这是某些人指出一个鲜为人知的系统的时候)。 - chris
3
请注意,const T* 并不总是指向一个 const T 的指针。它也可能意味着对可变的 T 的 "const 视图"。 当你使用 malloc 分配内存时,返回的内存总是被视为可变的(否则,你无法做任何事情)。这意味着,如果你打算释放它(因为它意味着是用 malloc 分配的,否则就是未定义行为),那么将 const T* 上的 const 去掉是完全安全的。 - KABoissonneault
1
@chris 我已经在存储指向 C 风格字符串的指针的情况下使用了该模式,没有人应该能够修改该字符串。仅有一个中心函数有时会释放内存并复制一个新字符串值。对于类的外部客户端,我可以分离实现和 getter。但我也希望有 const 作为类内简单保护的一种方式。如果你有更好的方法,请告诉我。 - Werner Henze
显示剩余4条评论
1个回答

3

std::free源自于C标准库。C语言没有重载,因此无法继承const重载。

C++标准库已经通过一些有用的重载扩展了继承的C库,但并没有为free添加const重载。

可能从来没有考虑过这样的重载,或者认为添加到标准中没有必要。我没有看到任何公开的建议书提议添加这样的重载,尽管我没有阅读所有曾经存在的提案,也没有参加任何委员会会议或研讨会,因此不能否认这类文件的存在可能性。

为了解决这种重载的缺乏,确实可以使用const_cast,在这个上下文中,它是完全安全的。


1
不需要重载。一个接受“const void *”类型参数的单一函数可以在C和C++中都使用。 - user743382
@hvd 当然可以。但是C++标准是否更改了C库函数的任何函数签名?委员会是否会考虑这样做?我不会这样假设,但也许会。也许C库将被更改,但我认为这不太可能成为他们的优先考虑事项,因为在C中,隐式const T* -> T*转换是合法的。 - eerorika
是的,C++标准已经更改了C库函数(如strchr)的函数签名,但这不是我想表达的。如果C委员会宣布free(const void*)是有意义的,并相应地调整其签名,那么C++可以采用这种方式。而且,标准C没有隐式的const T*-> T*转换,从未有过。C编译器可以自由支持它作为扩展。C++编译器也可以作为扩展来支持它,只是在C++中正确地执行可能会破坏SFINAE的使用,这就是为什么C++编译器通常不实现它的原因。 - user743382
@hvd 感谢您在隐式转换方面指正我。很高兴自己的错误被改正了。 - eerorika

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