当模板代码需要在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*
?
答案 0 :(得分:2)
从想要阅读你的代码的人的角度来看(即使你将来,从现在起6个月),最好尽可能清楚地表达这个想法,而不是尽量减少你的次数铸造。
在你的情况下使用union
说"它可以是一个"但它并没有对实际执行其使用情况进行任何检查。
OTOH具有实现const和非const访问函数(包括强制转换函数)的清晰接口,允许您执行运行时检查并相应地执行操作(错误消息?异常?)。
清晰的界面还有一个额外的好处,就是封装实现,这样你的客户端代码就不依赖于实现的内部结构 - 你的客户端代码只会将你的模板用作const或非const(取决于用法)和访问/演员功能将确保使用实际上是有效的。