首页 新闻 会员 周边 捐助

有关C++模板的一个问题

0
悬赏园豆:20 [已解决问题] 解决于 2009-02-04 09:30

初学stl,写了个用于显示容器内容的函数模板,但是在编译的时候就出错了。

ps.我只想用一个函数就可以显示所有容器,而不管它是关联容器还是序列容器

函数模板代码如下:

template<class _COLL>
void PrintAll( _COLL container)
{
for(_COLL::iterator it = container.begin(); it != container.end() ; ++it)
{
string tmpStr;

if( (string( typeid(*it).name() )).find_first_of("struct std::pair") != string::npos )
{
tmpStr
= (*it).second;
}
else
{
tmpStr
= *it ;
}

std::cout
<< "# " << tmpStr << std::endl;
}
}

 

然后在main中,调用PrintAll分别显示一个multimap和list

    std::multimap<int,string> my1stMap;
my1stMap.insert( std::make_pair(
1,"Y") );
my1stMap.insert( std::make_pair(
2,"H") );
my1stMap.insert( std::make_pair(
3,"J") );
my1stMap.insert( std::make_pair(
3,"Ji") );

PrintAll(my1stMap);

list
<int> intList;
intList.push_back(
1);
intList.push_back(
1);
intList.push_back(
1);

PrintAll(intList);

编译时报错:

Error    11    error C2679: binary '=' : no operator found which takes a right-hand operand of type 'std::pair<_Ty1,_Ty2>' (or there is no acceptable conversion)    e:\learnspace\Boost\Boost\Boost.cpp    72    Boost
Error    12    error C2228: left of '.second' must have class/struct/union    e:\learnspace\Boost\Boost\Boost.cpp    68    Boost

我觉得,应该是编译器检查“PrintAll(my1stMap)”时,因为it是个pair,所以tmpStr = *it 这条语句就通不过了。我本意是想在运行时通过typeid来区分,可是在编译期间就出错了,怎么呢?麻烦知道的c++大牛回答一下。

 

 

问题补充: 再补充一句:我知道特化可以做到,但是我想知道不用特化可以吗?
O和尚O的主页 O和尚O | 初学一级 | 园豆:170
提问于:2009-02-03 17:51
< >
分享
最佳答案
0
不是大牛,对C++稍有了解而已.

1, 不行.
没有通用的方法能做到这样的事情. 一个通用性非常差的方法可以这样做:

template<class _COLL>
void PrintAll( _COLL container)
{
for(_COLL::iterator it = container.begin(); it != container.end() ; ++it)
{
string tmpStr;

if( (string( typeid(*it).name() )).find_first_of("struct std::pair") != string::npos )
{
tmpStr
= (std::multimap<int,string>(*it)).second; //这里你根本不知道key是什么类型的--除非专门为multimap<T1,T2>做一个
特化
}
else
{
tmpStr
= string(*it ); //这里你也不知道collection里的数据是不是string,只能强制转型,后果是很可怕的
}

std::cout
<< "# " << tmpStr << std::endl;
}
}


2, 你用了C++,但是没有接受C++的思想,你的作法里动态的味道很浓. C++里没有Reflection,所以对编译期和运行期的区分很明显.
不要使用强制转型--这个相当于原子弹级别的东西,威力太大.强制转型本身在运行时几乎总是成功的--不像C#里会有InvalidCastException扔出来, 但是把Poison转型成Food的后果,是要出人命的.
deerchao | 大侠五级 |园豆:8367 | 2009-02-04 02:21
其他回答(1)
0

学习....

Jared.Nie | 园豆:1940 (小虾三级) | 2009-02-04 09:29
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册