I have two structs:
// ----- non-const -----
struct arg_adapter
{
EArgType type; // fmtA, fmtB, ...
union
{
TypeA * valueA;
I just stumbled about an even better way using the type selection ideom presentend by Alexandrescu in "Modern C++ Design":
This is the type selector:
template
struct Select { typedef T Result; }
template
struct Select { typedef U Result; }
Your class would then look like this:
template
struct arg_adapter
{
// define A and B as const or non-const
typedef typename Select::Result A;
typedef typename Select::Result B;
EArgType type; // fmtA, fmtB, ...
union
{
A * valueA; // this is either const TypeA* oder TypeA* depending on
// your choice of the isConst template parameter
B * valueB;
// ... more types
}
arg_adapter(A & value) : type(fmtA), valueA(&value) {} // same here with ref
arg_adapter(B & value) : type(fmtB), valueB(&value) {}
// ...
}
You can use typedefs for convenience:
struct nonconst_adapter : public arg_adapter {};
struct const_adapter : public arg_adapter {};
This was my old answer using simple type traits:
template
struct arg_adapter
{
typedef typename TypeTraits::T T;
void bar(T a) { ... } // by value/reference
void bar(T* a) { ... } // by pointer
}
template
struct NonConstTraits {
typedef K T;
}
template
struct ConstTraits {
typedef const K T;
}
template
struct nonconst_adapter : public arg_adapter > {};
template
struct const_adapter : public arg_adapter > {};