问题确实符合标题:我很想知道这种差异的技术原因是什么,还有理由?
std::shared_ptr<void> sharedToVoid; // legal;
std::unique_ptr<void> uniqueToVoid; // ill-formed;
Run Code Online (Sandbox Code Playgroud) 我想为OpenGL对象(纹理,帧缓冲区等)编写一个简单的RAII包装器.我注意到,所有glGen*和glDelete*函数共享相同的签名,所以我的第一次尝试是这样的:
typedef void (__stdcall *GLGenFunction)(GLsizei, GLuint *);
typedef void (__stdcall *GLDelFunction)(GLsizei, const GLuint *);
template <GLGenFunction glGenFunction, GLDelFunction glDelFunction>
class GLObject
{
GLuint m_name;
public:
GLObject()
{
glGenFunction(1, &m_name);
}
~GLObject()
{
glDelFunction(1, &m_name);
}
GLuint getName() {return m_name;}
};
typedef GLObject<glGenTextures, glDeleteTextures> GLTexture;
Run Code Online (Sandbox Code Playgroud)
它工作正常的纹理,但没有对帧缓冲器:glGenFramebuffers和glDeleteFramebuffers函数地址在编译时不知道,并不能作为模板参数.所以我做了第二个版本:
class GLObjectBase
{
GLuint m_name;
GLDelFunction m_delFunction;
public:
GLObjectBase(GLGenFunction genFunc, GLDelFunction delFunction)
: m_delFunction(delFunction)
{
genFunc(1, &m_name);
}
GLuint getName()
{
return m_name;
}
protected:
~GLObjectBase()
{ …Run Code Online (Sandbox Code Playgroud) 由于历史原因,我QSharedPointer<T>在我的软件中使用.在某些时候,我们希望boost::shared_ptr<T>将该点存储到相同的数据中,并且应该保持该实例的存活QSharedPointer<T>.
执行此操作的常用方法是在删除器中保留另一个智能指针的副本boost::shared_ptr<T>.但是,为了防止缺失者由具有不同类型不同Ts,这将防止容易得到一个QSharedPointer背部boost::get_deleter,当corrresponding boost::shared_ptr一直上溯造型,我想原来的存储QSharedPointer<T>作为一个QSharedPointer<void>在删除器内,而不是使用T.
但我发现这QSharedPointer不能胜任任务,因为它在编译其标题时会抛出诸如"无法完成无效"的错误.
有没有人知道如何在不暴露T于删除器的情况下完成这项工作?
所以gcc 4.9.0已实现一个static_assert离子该类型是不void被正确地符合标准.这很棒,一切都符合标准.
我有一个变体类型存储数据下std::unique_ptr<void>现在不起作用.简单的解决方法是将其更改为a std::shared_ptr<void>并立即编译.更好的解决方法是提供删除函数.
以下是一种安全的修复方法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;
}
Run Code Online (Sandbox Code Playgroud)