Why is the C++ STL is so heavily based on template

2020-01-27 08:58发布

I mean, aside from its obligating name (the Standard Template Library)...

C++ initially intended to present OOP concepts into C. That is: you could tell what a specific entity could and couldn't do (regardless of how it does it) based on its class and class hierarchy. Some compositions of abilities are more difficult to describe in this manner due to the problematics of multiple inheritance, and the fact that C++ supports the concept of interfaces in a somewhat clumsy way (compared to java, etc), but it's there (and could be improved).

And then templates came into play, along with the STL. The STL seemed to take the classical OOP concepts and flush them down the drain, using templates instead.

There should be a distinction between cases when templates are used to generalize types where the types themeselves are irrelevant for the operation of the template (containers, for examples). Having a vector<int> makes perfect sense.

However, in many other cases (iterators and algorithms), templated types are supposed to follow a "concept" (Input Iterator, Forward Iterator, etc...) where the actual details of the concept are defined entirely by the implementation of the template function/class, and not by the class of the type used with the template, which is a somewhat anti-usage of OOP.

For example, you can tell the function:

void MyFunc(ForwardIterator<...> *I);

Update: As it was unclear in the original question, ForwardIterator is ok to be templated itself to allow any ForwardIterator type. The contrary is having ForwardIterator as a concept.

expects a Forward Iterator only by looking at its definition, where you'd need either to look at the implementation or the documentation for:

template <typename Type> void MyFunc(Type *I);

Two claims I can make in favor of using templates: compiled code can be made more efficient, by tailor-compiling the template for each used type, instead of using vtables. And the fact that templates can be used with native types.

However, I am looking for a more profound reason why abandoning classical OOP in favor of templating for the STL? (Assuming you read that far :P)

13条回答
▲ chillily
2楼-- · 2020-01-27 09:33

How do you do comparisons with ForwardIterator*'s? That is, how do you check if the item you have is what you're looking for, or you've passed it by?

Most of the time, I would use something like this:

void MyFunc(ForwardIterator<MyType>& i)

which means I know that i is pointing to MyType's, and I know how to compare those. Though it looks like a template, it isn't really (no "template" keyword).

查看更多
登录 后发表回答