When you discriminate only on type, as in the above example code, you
can only have one member of each type.
If that restriction is OK with you then just make `store` a function
template:
template< class Arg >
auto store( Arg arg ) -> ObjPtr*
In the function body there are two main ways to select the member to
assign to, i.e. ways to specify the type -> member association. Maybe
there are other techniques too. But only two popped up in my brain now.
One way is to have a function overloaded for each relevant member type:
auto DataItem::member( int& ) -> int& { return aValueInt; }
auto DataItem::member( double& ) -> double& { return aValueDouble; }
// etc., then
template< class Arg >
auto DataItem::store( Arg arg )
-> ObjPtr*
{
// Do some stuff.
member( arg ) = move( arg );
// Do some more stuff.
return this;
}
Another way is to let the data members be base class sub-objects of
DataItem. Then they can be selected by `static_cast` to the relevant
type. Since one cannot derive from `int` or `double` it's necessary to
use some kind of boxing class, e.g.
template< class Value >
struct Boxed_
{
Value value;
};
class DataItem:
public ObjPtr,
private Boxed_<int>,
private Boxed_<double>,
// etc.
{
template< class Arg >
auto member( int& )
-> Arg&
{ return static_cast<Boxed_<Arg>&>( *this ).value; }
// + The `store` function template as before.
};
It's possible though that these techniques, while addressing directly
what you're asking for, don't address the Real Issue. Because inheriting
from an `ObjPtr` class, and returning a raw pointer from a `store`
method, indicate a struggling, unnatural design. So likely this is an
X/Y problem where you have a Real Issue X, you imagine that Y could be a
good solution to X, you can't make Y work cleanly, and you ask about Y?
- Alf