Can I extract C ++ template arguments from a template class?

In principle, this template class is as follows:

template< class Value > class Holder { }; 

I would like to know the type of Value for this class Holder . I thought I could make a simple metafound that takes a templated template argument, for example:

 template< template< class Value > class Holder > class GetValue { typedef Value Value; }; 

And then extract the value type as follows:

 GetValue< Holder< int > >::Value value; 

But instead, I just get an error message indicating a metafunction declaration:

 error: 'Value' does not name a type 

Is there any way to achieve this kind of thing? Thanks.

[EDIT] I also get error messages:

 error: type/value mismatch at argument 1 in template parameter list for 'template<template<class Value> class Holder> class GetValue' error: expected a class template, got 'Holder<int>' 

This leads me to conclude that Phil Nash is right, you cannot pass a class as an argument to a template template.

+3
source share
3 answers

Why don't you just change the holder class to

 template< class Value > class Holder { typedef Value value_type; value_type m_val; // member variable }; 

In any method that consumes an object of type Holder <T>, you can access the contained type:

 template< class THolder > void SomeMethod( THolder const& holder ) { typename THolder::value_type v = holder.m_val; } 

This approach follows a pattern that uses all STL classes, for example, std :: vector <int> :: value_type - int.

I think you are trying to do a partial specialization of templates:

 template<class T> class GetValue { }; template<class Value> class GetValue< Holder<Value> > { public: typedef Value value_type; }; 

In your code, you can do the following:

 template<class THolder> void SomeMethod( THolder const& h ) { typename GetValue< THolder >::value_type v = h.m_v; } 

In general, I would prefer the first solution.

+10
source
 template <class T> void extract_type(Holder<T>) { printf("%s\n", typeid(T).name()); } 

I assume you want to use this in a non-templated function. This is a little trickier:

 template <class T> class GetValue; template <class T> class GetValue<Holder<T> > { public: typedef T value_type; }; 

Google's magic words are a "private specialization"

+2
source

I think you need a name somewhere out there.

[edit] Damn, just about to test my suspicion that this should be before GetValue, but Mikola got there first :-)

The problem is that Value is a dependent type. The compiler does not know whether to indicate the type or value, so you need to provide a hint.

[edit2]

Unfortunately. There is a problem trying to respond too quickly. I missed the fact that you tried to use a template template to achieve this. This allows you to use a template instead of a type. In this case, you can transfer to the Holder. But this will not help you because you want to pass the type, Holder <int>.

It seems that Mikola understood this and deleted her answer.

To do this, you will need to use the Partial Template Specialization. Before I could finish my own example, Sebastian beat me :-)

+1
source

All Articles