Suppose I'm writing a container class `template <typename T> class MyContainer` and for some reason I would like to pass objects of type `T` with their type hidden from the user. In particular I would like to ensure that any input to `MyContainer::Foo` goes first through `MyContainer::HideType`.

```
template <typename T>
class MyContainer {
 public:
  ... constructors and stuff...

  HidesType& HideType(T&);      
  T& UnhideType(HidesType&);

  void Foo(HideType&);

  ... some other stuff...
};

```

Now I am wondering what HidesType can/should be. Some options are:

```
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); }

```

The problem with the first is that user can't keep `T` objects as

```
MyContainer<T>::HidesType tmp(HideType(t_obj));

```

because `tmp` will be invalid as soon as `t_obj` goes out of scope. Also, I'm not sure if the compiler will optimize away the HidesType completely. 

The problem with the second is that I don't know if the reinterpret\_cast is safe (e.g. won't there be any alignment issues?).

The problem with the third is that `T` might be marked `final` and HidesType& converts to T& implicitly.

Any thoughts or suggestions will be greatly appreciated.

**Edit:**

The main purpose of hiding is to make `HidesType` abstract and distinguishable from `T`.
It would be troublesome to explain all the context which led to this question. For now, let's assume that the function `MyContainer::Foo` essentially takes as an input `T`, however, I don't want the user to know/use that, in particular the interface might change in the future. 

Correct usecase could be:

```
MyContainer<T>::HidesType handle = MyContainer<T>::HideType(t_obj);
... do something ...
... perhaps t_obj.~T(); ...
... do something ...
my_container.Foo(handle);

```

Invalid usecase:

```
MyContainer<T>::HidesType handle = MyContainer<T>::HideType(t_obj);
... do something ...
my_container.Foo(some_other_t_obj);

```