2013-05-07 30 views
2

的类型有两种结构:C++,模板:获得该项目

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; 
}; 

和功能

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; 

} 

有什么办法如何让* I_L模板化的类型(此处双)即,

std::list::Item type 

而不经过任何其他参数如果

int main(int argc, char* argv[]) 
{ 
ABList <double> ::Type intervals; 

test (intervals); 


return 0; 
} 

感谢您的帮助,C++ 03是首选。

更新问题

如果一个模板化的类型

std::list::Item type 

代表测试)的正式参数(,此解决方案

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; 
} 

不工作...以下错误发生:

error C2770: invalid explicit template argument(s) 

版本

test (intervals, x); 

导致另一个错误:

Failed to specialize function template 'void test(List,List::value_type::{ctor})' 
+4

不完全相信你意思。你想要['std :: list :: value_type'](http://en.cppreference.com/w/cpp/container/list)。 – BoBTFish 2013-05-07 14:42:11

+0

另一种选择:写你自己type_traits为你类型。 – maverik 2013-05-07 14:50:10

+0

放弃了测试函数的显式模板参数,请尝试在main()中只调用test(intervals,x)并让“模板参数推导”找到函数的正确匹配。我试过了,它编译没有问题 – tmaric 2013-05-07 16:11:42

回答

2

可以typedef模板参数T在结构和使用std::list::value_type获得存储在结构AB,如果你不使用类型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; 
} 
+0

@ tomislav:谢谢,但是如果typename List :: value_type :: value_type Listval代表测试方法的形式参数,它不起作用。 – justik 2013-05-07 15:38:28

+0

不确定我明白你的意思:测试函数的形式参数是List模板参数,只要List符合STL,它的公共接口中就会有value_type typedef,并且如果将存储在List中的结构扩展到做同样的事,没有问题......或者我错过了什么? – tmaric 2013-05-07 15:46:06

+0

@ tomislav:感谢您的评论和帮助,我更新了问题... – justik 2013-05-07 16:06:47

3

在C++ 11,只要使用auto

auto val = (*il).a; 

如果以后需要参考该类型,你可以使用decltype(val)

在C++ 03,你可以得到基本类型的标准容器类型L为:

L::value_type 

所以你的情况应该是:

typename List::value_type 

在你的情况,然而,这会给你的类型AB,而不是AB::a的类型。如果您需要能够在编译时检索AB模板实例的类型T,则需要在AB内部提供某种类型的别名。例如:

template <typename T> 
struct AB 
{ 
    typedef T value_type; 
// ^^^^^^^^^^^^^^^^^^^^^ 

    T a, b; 

    AB <T> () : a (0.0), b (0.0) {} 
}; 

然后,你可以这样做:

typename List::value_type::value_type val = (*il).a; 

如果你不想改变的AB定义只是为了这个目的,你可以定义一个单独的类型特征,如以下:

template<typename T> 
struct underlying_type_of; 

template<typename T> 
struct underlying_type_of<AB<T>> 
{ 
    typedef T type; 
}; 

然后,您可以得到基本类型的AB<T>T如下图所示:

typename underlying_type_of<typename List::value_type>::type val = (*i_l).a;