【发布时间】:2014-08-03 04:58:44
【问题描述】:
假设我正在编写一个容器类template <typename T> class MyContainer,出于某种原因,我想传递T 类型的对象,并且它们的类型对用户隐藏。特别是我想确保对MyContainer::Foo 的任何输入都首先通过MyContainer::HideType。
template <typename T>
class MyContainer {
public:
... constructors and stuff...
HidesType& HideType(T&);
T& UnhideType(HidesType&);
void Foo(HideType&);
... some other stuff...
};
现在我想知道 HidesType 可以/应该是什么。一些选项是:
struct HidesType {
HidesType(T& data) : data_(data) { }
T& data_;
};
HidesType HideType(T& data) { return HidesType(data); }
union HidesType { T data_; };
HidesType& HideType(T& data) { return reinterpret_cast<HidesType&>(data); }
class HidesType : public T { };
HidesType& HideType(T& data) { return static_cast<HidesType&>(data); }
第一个问题是用户不能将T对象保留为
MyContainer<T>::HidesType tmp(HideType(t_obj));
因为一旦t_obj 超出范围,tmp 就会失效。另外,我不确定编译器是否会完全优化 HidesType。
第二个的问题是我不知道 reinterpret_cast 是否安全(例如不会有任何对齐问题吗?)。
第三个问题是 T 可能被标记为 final 并且 HidesType& 隐式转换为 T&。
任何想法或建议将不胜感激。
编辑:
隐藏的主要目的是使HidesType抽象并与T区分开来。
解释导致这个问题的所有背景会很麻烦。现在,让我们假设函数MyContainer::Foo 本质上将T 作为输入,但是,我不希望用户知道/使用它,特别是接口可能在未来发生变化。
正确的用例可能是:
MyContainer<T>::HidesType handle = MyContainer<T>::HideType(t_obj);
... do something ...
... perhaps t_obj.~T(); ...
... do something ...
my_container.Foo(handle);
无效的用例:
MyContainer<T>::HidesType handle = MyContainer<T>::HideType(t_obj);
... do something ...
my_container.Foo(some_other_t_obj);
【问题讨论】:
-
这种隐藏的目的是什么,具体在什么情况下该类型应该“隐藏”,“隐藏”是什么意思?
-
我认为客户端代码不可能实现的示例将有助于澄清事情。
-
鉴于用户首先提供了模板类型,我不确定您是否可以对用户隐藏模板类型。
-
@Cheersandhth.-Alf 查看编辑。隐藏的主要目的是使
HidesType抽象并与T区分开来。 -
@Galik 我想隐藏的不是
T本身,而是MyContainer::Foo将T作为参数这一事实。
标签: c++ c++11 casting type-conversion