前几天,有博主看了一篇批评C++泛型生成的可执行代码膨胀的文章。博主从事C++软件开发多年。由于之前的开发环境是一台资源充足的服务器,所以不需要考虑磁盘空间的问题。最近打算在智能家居主机的嵌入式平台上使用C++进行开发。FLASH存储空间是有限的,这是必须要考虑和必须注意的一个因素。如下定义两个列表,元素类型不同:listl1;列表<字符串>l2;用C语言做的话怎么办?它将为list编写一组代码,为list编写另一组代码。每个集合都有相同的成员函数,但变量类型不同。下面是list的C语言实现://!code-1structlist_int_item{intvalue;structlist_int_item*next;};structlist_int{structlist_int_item*head;size_tsize;};voidlist_int_insert(structlist_int*p,intvalue);intlist_int_sort(structlist_int*p);boollist_int_empty(structlist_int*p);...下面是list的C语言实现://!code-2structlist_string_item{stringvalue;structlist_string_item*next;};structlist_string{structlist_string_item*head;size_tsize;};voidlist_string_insert(structlist_int*p,stringvalue);intlist_string_sort(structlist_int*p);boollist_string_empty(structlist_int*p);...两者的区别在于类型。所以很多时候,我们在C语言中用宏来代替它的类型,如下://!code-3#defineLIST_DECLARE(TYPE)\structlist_##TYPE##_item{\TYPE##value;\structlist_##TYPE##_item*next;\};\\structlist_##TYPE{\structlist_##TYPE##_item*head;\size_tsize;\};\\voidlist_##TYPE##_insert(structlist_##TYPE*??p,##TYPE##value);\intlist_##TYPE##_sort(structlist_##TYPE*??p);\boollist_##TYPE##_empty(structlist_##TYPE*??p);\...然后在header文件这样定义list://!code-4LIST_DECLARE(double)所以,泛型产生冗余代码是不可避免的,至少用C来做这样的泛型是不可避免的。既然无法避免,那我们就看看如何尽量避免以上问题。《Effective C++》中有一章专门提到:不要在模板中使用不必要的参数。因为编译器会为每一个不同的参数生成一组对应的代码。如果代码中只有一种数据类型,即使定义了多个变量,编译器是否也只会生成一组相关的代码?(应该是这样的)。写个例子对比一下:(省略不必要的代码)test1.cpp只包含map,但定义了m1,m2,m3。//!code-5mapm1;mapm2;mapm3;m1.insert(std::make_pair(1,"hello"));m2.insert(std::make_pair(1,"hi"));m3.insert(std::make_pair(1,"licunjun"));test2.cpp,与test1.cpp相比,一共有三种://!code-6mapm1;mapm2;mapm3;m1.insert(std::make_pair(1,"hello"));m2.insert(std::make_pair(1,1.2));m3.insert(std::make_pair(1,44));结果编译出来的可执行文件大小对比:[hevake_lcj@Hevaketmp]$lltest1test2-rwxrwxr-x.118784Mar1922:01test1-rwxrwxr-x.135184Mar1922:03test2test2是test1的两倍,原因不用说了。还有一个问题:指针是否被视为一种类型?上面的list和list不能共享同一组代码。原因是int和string这两种类型在空间大小和赋值方式上是不同的。因此,必须生成两套代码来实现这一点。还有指针,不管它们是什么,它们都是一样的。我们可以使用void*来表示所有的指针类型。于是我们改了上面的代码,再次测试://!code-7mapm1;mapm2;mapm3;m1.insert(std::make_pair(1,newstring("hello")));m2.insert(std::make_pair(1,newstring("hi")));m3.insert(std::make_pair(1,newstring("lichunjun")));使用//!code-8mapm1;mapm2;mapm3;m1.insert(std::make_pair(1,newstring("hello")));m2.insert(std::make_pair(1,newdouble(1.2)));m3.insert(std::make_pair(1,newint(44)));结果是这样的:-rwxrwxr-x.118736Mar1923:05test1-rwxrwxr-x.135136Mar1923:05test2test1和test2的预期结果差不多,但是结果没有优化,结果有点失望~思考:C++中是否有任何参数可以对此进行优化?如果不是,为了节省篇幅,我们只能将所有的指针统一定义为void*类型,然后在使用时进行强制转换。//!code-9mapm1;mapm2;mapm3;m1.insert(std::make_pair(1,newstring("hello")));m2.insert(std::make_pair(1,newdouble(1.2)));m3.insert(std::make_pair(1,newint(44)));cout<<*static_cast(m1[1])<(m2[1])<(m3[1])<