在void *中存储指向T的指针,但T可能是const或nonconst - 使用void const *或只是void *?

时间:2017-02-15 17:58:07

标签: c++ const void-pointers type-erasure

当模板代码需要在T*类型的变量中存储void*时,可以检索它并稍后将其转换回T*,但它需要同时处理T {1}}和T const*,是否应使用void*void const*作为类型删除存储? (任何一种选择都需要在某处至少有一个const cast。)

(假设程序在运行时跟踪放入void *的内容,以确保它只检索与放入的内容相同的类型,但它在编译时不知道将在哪个类型中存储可变的。)

编辑:还假设未键入的存储隐藏在具有模板化set()和get()方法的包装类后面,该方法记录了用于set()调用的T,如果不同则抛出异常T用于get()。所以问题是关于包装类应该如何存储它。 (注意:包装类本身不是模板;只是它的方法set()和get()是模板。)

过去,当问题出现时我使用了union { void* p_nc; void const* p_c; };。但是,我想知道与仅仅使用const_cast相比,这是否过度。

问题是,哪种方式更好(如果有的话):在T const*存储时将const转换为void*,或者使用void* const存储并转换const如果检索一个nonconst T*

1 个答案:

答案 0 :(得分:2)

从想要阅读你的代码的人的角度来看(即使你将来,从现在起6个月),最好尽可能清楚地表达这个想法,而不是尽量减少你的次数铸造。

在你的情况下使用union说"它可以是一个"但它并没有对实际执行其使用情况进行任何检查。

OTOH具有实现const和非const访问函数(包括强制转换函数)的清晰接口,允许您执行运行时检查并相应地执行操作(错误消息?异常?)。

清晰的界面还有一个额外的好处,就是封装实现,这样你的客户端代码就不依赖于实现的内部结构 - 你的客户端代码只会将你的模板用作const或非const(取决于用法)和访问/演员功能将确保使用实际上是有效的。