当前位置:编程学习 > C/C++ >>

自定义类型的思考

最近在群里面看到这样一个语句:typedef typename T::value_type _type; 我的第一反应这是一个自定义类型,没错确实是一句自定义类型,但这和我们平常见到的自定义类型又有不同,T::value_type 这块会让大多数人和很不解。其实他的意义就是:这个T必须含有value_type这个成员,也就是说T必须是个类或者命名空间,如果还不明白继续往下看。

[cpp]
// 自定义类型1-这是常规自定义类型的变形,首先传入的classType应该是个类且必须有value_type这个成员,例如STL中的类. 
template<class classType,class keyType = int,class valueType = char*> 
struct CCustomType 

    typedef typename classType::value_type custom_type; 
    custom_type data; 
};  

使用CCustomType自定义类型:
[cpp] 
CCustomType<string>   string_; 
string_.data = 'c';                     // string::value_type 是char 类型,从下面的basic_string就可以看出 
 
CCustomType<basic_string<char,char_traits<char>,allocator<char>>>   string_2; 
string_2.data = 'x';                        // char 
 
CCustomType<list<char*>>    list_; 
list_.data = "you are so beautiful";                // char* 
 
CCustomType<set<UINT>>  set_; 
set_.data = 512139461;                      //  UINT 

声明CCustomType<map<int,char*>,int,char*> pair_;
这里pair_.data 是map的成员value_type也就是pair类型,更具体的讲是pair<int,char*> #
在使用CCustomType<map<int,char*>,int,char*>之前,我们先看下stl中pair的用法:
[cpp]
std::pair<int,char*> pair_1(2012,"hello world");      // 利用构造函数初始化pair_1 
// 
std::pair<int,char*> pair_2; 
pair_2 = make_pair(1989,(char*)"hansen");           // ok make_pair赋值 
// 
pair_2.first = 2000;                        // ok  
pair_2.second = "just test";                    // ok 
// 
map<int,char*> nMap; 
nMap.insert(pair_1);                                 
nMap.insert(pair_2);                         
 
CCustomType<map<int,char*>,int,char*> pair_;// ok map应该这样用,key是int型 ,value是char*类型 
//(pair_.data).first = 2012; error C3892: “pair_”: 不能给常量赋. 
//通过监视查看pair_.data.first是个const int类型为什么会变成const int,我传入的是<int,char*>类型,应该是pair<int,char*>类型,开始我也有这个疑问. 
(pair_.data).second = "that's ok";          // ok,value不是const的,可以赋值 

分析:
[cpp]
//按照上面的原型,声明一个pair类型变量 pair_test 
map<int,char*>::value_type pair_test(2013,"test test"); 
 
// 通过源码一步步跟进查看这个map的value_type,first:const int ,second:char* 
// 1.map的value_type来自_Mybase的成员value_type: 
typedef typename _Mybase::value_type value_type; 
// 2.继续跟发现_Mybase是个模板类,由_Tmap_traits构造: 
typedef _Tree<_Tmap_traits<_Kty, _Ty, _Pr, _Alloc, false> > _Mybase; 
// 3.就要揭晓答案了,跟_Tmap_traits发现原来他自定义了pair类型: 
typedef pair<const _Kty, _Ty> value_type; 
// 4.这就是为什么map的key是个const类型,也表明上面的自定义类型CCustomType的data成员实际上是个pair<const T,T> 

那么有什么办法可以给自定义类型CCustomType的data成员赋值呢,答案是通过构造函数,我们先对CCustomType做下变形:
[cpp] 
template<class classType,class keyType = int,class valueType = char*> 
struct CCustomTypeEx 

    typedef typename classType::value_type custom_type;          
    custom_type data; 
    CCustomTypeEx() {} 
    CCustomTypeEx(keyType _key,valueType _value) 
        :data(_key,_value)                  // 调用classType::pair的构造函数 
    { 
    } 
 
}; www.zzzyk.com
[cpp] 
CCustomTypeEx<map<int,char*>,int,char*> pair_ex(1989,"hansen");     // ok 

总结:关于CCustomType<map,int,char*> pair_那个问题,其实在一开始我就偷换掉了概念,前面有句打#的就是理解不完全,死死认定pair_.data是个pair类型坚信pair是可以在构造后赋值的,没错常规的pair确实可以这样做,但我忘记了CCustomType中关键的一句typedef typename classType::value_type custom_type;也就是说这个value_type一定要是classType的成员,所以pair_.data 应该是map::value_type类型,进一步就是pair<const int,char*>类型.

补充:软件开发 , C++ ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,