views:

86

answers:

4

If a pointer to an user defined type is passed as template argument to a template class, is it possible to get the class type of the argument?

template <class T> struct UserType {
    typedef T value_type;
    ...
};

int main () {
    typedef std::vector<UserType<double>*> vecType
    vecType vec;

    vecType::value_type::value_type m; //how to get the double here?

    return 0;
}
+3  A: 

Use traits:

template <typename> struct ptr_traits {};
template <typename T> struct ptr_traits<T*>
{ typedef T value_type; };

ptr_traits<vecType::value_type>::value_type m;
Alexandre C.
Works like a charm, thx
DaClown
+5  A: 

Use boost::remove_pointer.

Polybos
I'm not a huge fan of boost (yet) and I can't accept a quarter liner, even if it is a proper way for my problem. Thanks anyway.
DaClown
I would not recommand using boost for such a simple thing. Boost's awesomeness comes from its complex libraries.
Alexandre C.
@Alex if you already use boost, it's fine to use boost for this thing.
Johannes Schaub - litb
@litb: of course.
Alexandre C.
A: 

Let me ask you what do you mean by "getting" the type?

You can actually use this type, for instance you may declare new variables of this type (as you demonstrate in your example), without explicitly specifying it.

Do you mean you want a textual description of the type?

If this is the case - there's no generic 100%-working way of doing it. This is because after compilation + link type and variable/function names vanish. They just don't exist at runtime.

You may however write some extra code to get the textual description of the types you need. One of the ways to do this:

template <typename T> const char* TypeName();
template <> const char* TypeName<int>() { return "int"; }
template <> const char* TypeName<double>() { return "double"; }
// ...

You'll get a linker error if you try to use TypeName on a type whose name you didn't yet define. Then you'll have to add the appropriate template specialization of TypeName.

valdo
As shown in the example code I would like to use the actual nested type as type for other variables (, ...). But a pointer to a type is not exactly the type und therefore the inner typedef doesn't work.
DaClown
oh, I see.Then I gueess Alexandre C. answers your question :)
valdo
+2  A: 

Traits are probably the way to go here.

Alternatively, you could introduce another typedef and use this in the declaration of vecType and m:

typedef UserType<double>* UserTypeDoublePtr;
typedef std::vector<UserTypeDoublePtr> vecType;

UserTypeDoublePtr m;
Johnsyweb
I like that second suggestion. I don't think it fits the actual need but I'll safe it for later. Traits work fine.
DaClown