STL/CLR
当大量使用STL的C++开发者转向.NET1/1.1时一定感觉非常别扭,他们中的许多可能会放弃并转回到原来的本机编码。从技术上讲,你能结合.NET类型(using gcroot)使用本机STL,但是产生的结果代码可能相当低效,更不用说是丑陋了:
std::vector< gcroot<IntPtr> >* m_vec_hglobal;
//...
for each(gcroot<IntPtr> ptr in *m_vec_hglobal)
{ Marshal::FreeHGlobal(ptr);}
大概VC++小组考虑到了这些并决定在Whidbey以后,他们会提供STL.NET(或STL/CLR)并可以单独从网上下载。
你可能问为什么?Stan Lippman,在他的MSDN文章(STL.NET Primer)中给出了3条原因:
·可扩展性--STL设计把算法和容器隔离到自己的应用空间-也就是你可以有一组容器和一组算法,并且你能在任何一个容器上使用这些算法;同时你能在任何一个算法中使用这些容器。因此,如果你添加一种新的算法,你能在任何一种容器中使用它;同样,一个新的容器也可以与现有算法配合使用。
·统一性--所有核心C++开发者集中在一起,汇集起他们精妙的STL专长,再使用他们的专长则轻车熟路。要较好地使用STL需要花费时间-然而一旦你掌握了它,你就有了在.NET世界中使用你的技巧的明显优势。不是吗?
·性能--STL.NET通过使用实现泛型接口的托管模板实现。并且既然它的核心已用C++和托管模板编码,可以期盼它比在BCL上使用的泛型容器更具有性能优势。
使用过STL的人不需要任何示范,所以下面代码有益于以前没有使用过STL的人。
vector<String^> vecstr;
vecstr.push_back("wally");
vecstr.push_back("nish");
vecstr.push_back("smitha");
vecstr.push_back("nivi");
deque<String^> deqstr;
deqstr.push_back("wally");
deqstr.push_back("nish");
deqstr.push_back("smitha");
deqstr.push_back("nivi");
我使用了两个STL.NET容器-vector和deque,并装满两个容器,使其看起来相同(在两个容器中都使用了push_back)。现在,我将在两个容器上使用replace算法-我们再次看到,这些代码是很相同的。
replace(vecstr.begin(), vecstr.end(),
gcnew String("nish"), gcnew String("jambo"));
replace(deqstr.begin(), deqstr.end(),
gcnew String("nish"), gcnew String("chris"));
这里特别要注意的是我使用了"同样"的算法--replace并在两个不同STL容器上使用相同的函数调用。这是当Stan谈及"可扩展性"时的意思。下面我用一个简单函数来证明:
template<typename ForwardIterator> void Capitalize(
ForwardIterator first,ForwardIterator end)
{
for(ForwardIterator it = first; it < end; it++)
*it = (*it)->ToUpper();
}
它遍历一个System::String^容器并把其中的每个字符串转化为大写。
Capitalize(vecstr.begin(), vecstr.end());
Capitalize(deqstr.begin(), deqstr.end());
for(vector<String^>::iterator it = vecstr.begin();
it < vecstr.end(); it++)
Console::WriteLine(*it);
Console::WriteLine();
for(deque<String^>::iterator it = deqstr.begin();
it < deqstr.end(); it++)
Console::WriteLine(*it);
上面我的算法能够与vector和deque容器工作良好。至此,不再细谈;否则,guru站上的STL爱好者们会对我群起攻击,而非STL人可能感到厌烦。如果你还没使用过STL,可以参考有关资料。