C++, templates: get type of the item
Solution 1
You can typedef
the template parameter T in the struct and use std::list::value_type
to get the type stored in the struct AB if you don't use C++11:
#include<list>
#include<iostream>
template <typename T>
struct AB
{
T a, b;
typedef T value_type;
AB( )
:
a (0),
b (0)
{}
};
template <typename T>
struct ABList
{
typedef std::list < AB <T> > Type;
typedef T Type2;
};
template <typename List>
void test ( List & l )
{
typename List::iterator i_l = l.begin();
typename List::value_type::value_type& Listval = i_l->a;
std::cout << Listval << std::endl;
}
template <typename List>
void test (List l, typename List::value_type::value_type val )
{
std::cout << "test" << std::endl;
}
int main(int argc, char* argv[])
{
ABList <double> ::Type intervals;
double x = 7.0;
test(intervals, x);
return 0;
}
Solution 2
In C++11, just use auto
:
auto val = (*il).a;
And if you need to refer to that type later, you can use decltype(val)
.
In C++03, you can get the underlying type for a standard container type L
as:
L::value_type
So in your case it should be:
typename List::value_type
In your case, however, that would give you the type AB
, and not the type of AB::a
. If you need to be able to retrieve at compile time the type T
for an instance of the AB
template, you need to provide some type alias inside AB
. For instance:
template <typename T>
struct AB
{
typedef T value_type;
// ^^^^^^^^^^^^^^^^^^^^^
T a, b;
AB <T> ( ) : a ( 0.0 ), b ( 0.0 ) {}
};
Then you could do:
typename List::value_type::value_type val = (*il).a;
If you do not want to alter the definition of AB
just for this purpose, you can define a separate type trait, such as the following:
template<typename T>
struct underlying_type_of;
template<typename T>
struct underlying_type_of<AB<T>>
{
typedef T type;
};
You could then get the underlying type T
of AB<T>
as shown below:
typename underlying_type_of<typename List::value_type>::type val = (*i_l).a;
justik
Updated on June 04, 2022Comments
-
justik almost 2 years
There are two structures:
template <typename T> struct AB { T a, b; AB <T> ( ) : a ( 0.0 ), b ( 0.0 ) {} }; template <typename T> struct ABList { typedef std::list < AB <T> > Type; typedef T Type2; };
and a function
template <typename List> void test ( List l ) { List::iterator i_l = l.begin(); //Here *i_l type is needed instead of double double val = (*il).a; }
Is there any way how to get *i_l templatized type (here double), i.e,
std::list::Item type
without passing any other parameter if
int main(int argc, char* argv[]) { ABList <double> ::Type intervals; test (intervals); return 0; }
Thanks for your help, C++ 03 is preferred.
Updated question
If a templatized type
std::list::Item type
represents a formal parameters of test(), this solution
template <typename List> void test ( List l, typename List::value_type::value_type val ) { ... } int main(int argc, char* argv[]) { ABList <double> ::Type intervals; double x = 7.0; test <ABList<double>> (intervals, x); return 0; }
does not work... The following error occurs:
error C2770: invalid explicit template argument(s)
The version
test (intervals, x);
causes another error:
Failed to specialize function template 'void test(List,List::value_type::{ctor})'
-
justik almost 11 years@ tomislav: Thanks, but if typename List::value_type::value_type Listval represents a formal parameter of the test method, it does not work.
-
tmaric almost 11 yearsnot sure I get what you mean: the formal parameter of the test function is the List template parameter, as long as the List is STL compliant it will have value_type typedef in its public interface, and if you extend the structure stored in List to do the same, there is no problem... or am I missing something?
-
justik almost 11 years@ tomislav: omitting specialization causes another error :-(.
-
tmaric almost 11 years@justik: I've modified the code, it compiles on g++ (Ubuntu 4.4.3-4ubuntu5.1) 4.4.3
-
justik almost 11 years@ tomislav: Yes, you are right. I checked g++ (OK), but VS 2010 compiler does not work... I am going to create a new thread with the simplified example... Once again, thanks for your help.