Tải bản đầy đủ - 0 (trang)
Appendix B. Remarks on Microsoft’s STL Platforms

Appendix B. Remarks on Microsoft’s STL Platforms

Tải bản đầy đủ - 0trang

...

vw.insert(vw.end(), dw.begin(), dw.end());

copy



// append to vw a

// of the Widgets in



dw



In fact, you can do this no matter what the type of the container holding the

objects to be copied. Even custom containers work:

Click here to view code image

vector vw;

...

list lw;

...

vw.insert(vw.begin(), lw.begin(), lw.end());

copy



// prepend to vw a

// of the Widgets in



lw

set sw;

...

vw.insert(vw.begin(), sw.begin(), sw.end());

copy



// prepend to vw a

// of the Widgets in



sw

template
custom

typename Allocator = allocator >

class SpecialContainer { ... };



// template for a

// STL-compatible

// container



SpecialContainer scw;

...

vw.insert(vw.end(), scw.begin(), scw.end());



// append to vw a copy

// of the Widgets in



scw



This flexibility is possible because vector’s range insert function isn’t a

function at all. Rather, it’s a member function template that can be

instantiated with any iterator type to generate a specific range insert function.

For vector, the Standard declares the insert template like this:

Click here to view code image

template >



class vector {

public:

...

template

void insert(iterator position, InputIterator first, InputIterator

last);

...

};



Each standard container is required to offer this templatized range insert.

Similar member function templates are required for the containers’ range

constructors and for the range form of assign (both of which are discussed in

Item 5).



MSVC Versions 4–6

Unfortunately, the STL implementation that ships with MSVC versions 4–6

declares no member function templates. This library was originally developed

for MSVC version 4, and that compiler, like most compilers of its day, lacked

member function template capabilities. Between MSVC4 and MSVC6, the

compiler added support for these templates, but, due to legal proceedings that

affected Microsoft without directly involving them, the library remained

essentially frozen.

Because the STL implementation shipping with MSVC4–6 was designed for

a compiler lacking member function templates, the library’s authors

approximated the functionality of such templates by replacing each template

with a specific function, one that accepted only iterators from the same

container type. For insert, for example, the member function template was

replaced with this:

Click here to view code image

void insert(iterator position,

iterator first, iterator last);

iterator type



// "iterator" is the

// container's



This restricted form of range member functions makes it possible to perform

a range insert from a vector to a vector or from a list to a

list, but not from a vector to a list or from a set to a

deque. It’s not even possible to do a range insert (or assign or construction)



from a vector to a vector, because vector::iterator is not the same

type as a vector::iterator. As a result, the following perfectly valid code

fails to compile using MSVC4–6:

Click here to view code image

istream_iterator begin(cin), end;



// create begin and end

// iterators for



reading

// Widgets from cin

// (see Item 6)

vector vw(begin, end);

into vw



// read cin's Widgets

// (again, see Item 6);



won't

// compile with MSVC4-6

list lw;

...

lw.assign(vw.rbegin(), vw.rend());

to lw



// assign vw's contents

// (in reverse order);



won't

// compile with MSVC4-6

SpecialContainer scw;

...

scw.insert(scw.end(), lw.begin(), lw.end());

scw a



// insert at the end of

// copy of the Widgets



in lw;

// won't compile with

MSVC4-6



So what do you do if you must use MSVC4–6? That depends on the MSVC

version you are using and whether you are forced to use the STL

implementation that comes with the compiler.



A Workaround for MSVC4–5

Look again at the valid code examples that fail to compile with the STL that

accompanies MSVC4–6:

Click here to view code image

vector vw(begin, end);

MSVC4-6



// rejected by the

//STL implementation



list lw;

...

lw.assign(vw.rbegin(), vw.rend());



//also rejected



SpecialContainer scw;

...

scw.insert(scw.end(), lw.begin(), lw.end());



// ditto



These calls look rather different, but they all fail for the same reason: missing

member function templates in the STL implementation. There’s a single cure

for all of them: use copy and an insert iterator (see Item 30) instead. Here, for

example, are the workarounds for the examples above:

Click here to view code image

istream_iterator begin(cin), end;

vector vw;

construct vw;

copy(begin, end, back_inserter(vw));



// default// then copy the

// Widgets in cin



into it

list lw;

...

lw.clear();

old

copy(vw.rbegin(), vw.rend(), back_inserter(lw));

over



// eliminate lw's

// Widgets; copy

// vw's Widgets



(in

// reverse order)

SpecialContainer scw;

...

copy(lw.begin(), lw.end(),

Widgets to

inserter(scw, scw.end()));



// copy lw's

// the end of scw



I encourage you to use these copy-based workarounds with the library that

ships with MSVC4–5, but beware! Don’t fall into the trap of becoming so

comfortable with the workarounds, you forget that they are workarounds. As

Item 5 explains, using the copy algorithm is almost always inferior to using a

range member function, so as soon as you have a chance to upgrade your

STL platform to one that supports member function templates, stop using copy

in places where range member functions are the proper approach.



An Additional Workaround for MSVC6



You can use the MSVC4–5 workaround with MSVC6, too, but for MSVC6

there is another option. The compilers that are part of MSVC4–5 offer no

meaningful support for member function templates, so the fact that the STL

implementation lacks them is immaterial. The situation is different with

MSVC6, because MSVC6’s compiler does support member function

templates. It thus becomes reasonable to consider replacing the STL that

ships with MSVC6 with an implementation that provides the member

function templates the Standard prescribes.

Item 50 explains that both SGI and STLport offer freely downloadable STL

implementations, and both of those implementations count the MSVC6

compiler as one with which they’ll work. You can also purchase the latest

MSVC-compatible STL implementation from Dinkumware. Each option has

advantages and disadvantages.

SGI’s and STLport’s implementations are free, and I suspect you know what

that means as regards official support for the software: there isn’t any.

Furthermore, because SGI and STLport design their libraries to work with a

variety of compilers, you will probably have to manually configure their

implementations to get the most out of MSVC6. In particular, you may have

to explicitly enable support for member function templates, because, working

with many compilers as they do, SGI and/or STLport may not enable that by

default. You may also have to worry about linking with other MSVC6

libraries (especially DLLs), including things like making sure you use the

appropriate builds for threading and debugging, etc.

If that kind of thing scares you, or if you’ve been known to grumble that you

can’t afford free software, you may want to look into Dinkumware’s

replacement library for MSVC6. It’s designed to be drop-in compatible with

the native MSVC6 STL and to maximize MSVC6’s adherence to the

Standard as an STL platform. Since Dinkumware authored the STL that ships

with MSVC6, there’s a decent chance their latest STL implementation really

is a drop-in replacement. To learn more about Dinkumware STL

implementations, visit the company’s web site:

http://www.dinkumware.com/.

Regardless of whether you choose SGI’s, STLport’s, or Dinkumware’s

implementation as an STL replacement, you’ll do more than gain an STL

with member function templates. You’ll also bypass conformance problems

in other areas of the library, such as string failing to declare push_back.



Furthermore, you’ll gain access to useful STL extensions, including hashed

containers (see Item 25) and singly linked lists (slists). SGI’s and STLport’s

implementations also offer a variety of nonstandard functor classes, such as

select1st and select2nd (see Item 50).

Even if you’re trapped with the STL implementation that ships with MSVC6,

it’s probably worth your while to visit the Dinkumware web site. That site

lists known bugs in the MSVC6 library implementation and explains how to

modify your copy of the library to reduce its shortcomings. Needless to say,

editing your library headers is something you do at your own risk. If you run

into trouble, don’t blame me.



Footnotes





If you’re interested in the tortured history of auto_ptr standardization, point

your web browser to the auto_ptr Update page [29] at the More Effective C++

web site.





This is true only for the forms of erase that take iterator arguments.

Associative containers also offer a form of erase taking a value argument, and

that form returns the number of elements erased. Here, however, we’re

concerned only with eraseing things via iterators.





There’s a loophole in the guarantee. If an exception is not caught at all, the

program will terminate. In that case, local objects (such as lock) may not have

their destructors called. Some compilers call them, some do not. Both

behaviors are valid.





Because log1.51000 = 18 (rounding up to an integer).







See Andrei Alexandrescu’s column in the April 2000 C++ Report [19].



Index

The example classes and class templates declared or defined in this book are

indexed under example classes/templates. The example functions and

function templates are indexed under example functions/templates.



Before A

__default_alloc_template



211C



A

abstraction bonus, 203C

abstraction penalty, 201C

accumulate



function objects for, 158C

initial value and, 157C, 159C

side effects and, 160C

adaptability

algorithm function objects and, 156C

definition of, 170C

functor classes and, 169–173C

overloading operator() and, 173C

add or update functionality, in map, 107C

adjacent_difference, 157C

advance



efficiency of, 122C

to create iterators from const_iterators, 120–123C

Alexandrescu, Andrei, 227C, 230C

algorithms

accumulate 156–161C

function objects for, 158C

initial value and, 157C, 159C

side effects and, 160C

adaptable function objects and, 156C



, 157C

as a vocabulary, 186C

binary_search, 192–201C

container mem funcs vs. 192C

copy, eliminating calls to, 26C

copy_if, implementing, 154–156C

copying func objects within, 166–168C

count, 156C, 192–201C

equal_range vs., for sorted ranges, 197C

count_if, 157C

efficiency, vs. explicit loops, 182–184C

equal_range, 192–201C

count vs., for sorted ranges, 197C

find, 192–201C

count in multiset, multimap vs. 199C

lower_bound in multiset , multimap vs. 201C

using equivalence vs. equality, 86C

for_each, 156–161C

side effects and, 160C

function call syntax in, 175C

function parameters to, 201–205C

hand-written loops vs. 181C–189C

includes, 148C

inner_product, 157C

inplace_merge, 148C

lexicographical_compare, 153C

longest name, 153C

loops and, 182C

lower_bound, 192–201C

equality vs. equivalence and, 195C

max_element, 157C

merge, 148C, 192C

min_element, 157C

adjacent_difference



, 151C

nth_element, 133–138C

optimizations in, 183C

partial_sort, 133–138C

partial_sum, 157C

partition, 133–138C

containers of pointers and, 145C

remove, 139–143C

on containers of pointers, 143–146C

remove_copy_if, 44C

remove_if, 44C, 144C, 145C

see also remove

possible implementation of, 167C

set_difference, 148C

set_intersection, 148C

set_symmetric_difference, 148C, 153C

set_union, 148C

sort, 133–138C

sorted ranges and, 146–150C

sorting, 133–138C

alternatives to, 138C

stable_partition, 133–138C

stable_sort, 133–138C

string member functions vs. 230C

transform, 129C

unique, 145C, 148C, 149C

see also remove

unique_copy, 148C, 149C

upper_bound, 197–198C

All your base are belong to us

allocations

minimizing via reserve, 66–68C

minimum, in string, 72C

mismatch



allocator

allocate



interface, vs. operator



, 51C



new



allocators

boilerplate code for, 54C

conventions and restrictions, 48–54C

fraud in interface, 51C

in string, 69C

legitimate uses, 54–58C

never being called, 52C

permitted assumptions about, 49C

rebind template within, 53C

stateful, portability and, 50C, 51C, 212C

summary of guidelines for, 54C

typedefs within, 48C

URLs for examples, 227C, 228C

allusions

to Candide, 143C

to Do Not Go Gentle into that Good Night, 187C

to Martin Luther King, Jr. 51C

to Matthew, 25 222C

to The Little Engine that Could, 63C

amortized constant time complexity, 6C

ANSI Standard for C++

see C++ Standard, The

anteater, 88C

argument_type, 170C

array-based containers, definition of, 13C

arrays

as part of the STL, 2C

as STL containers, 64C

containers vs. 22C

vector and string vs. 63C–66C

assignments



Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Appendix B. Remarks on Microsoft’s STL Platforms

Tải bản đầy đủ ngay(0 tr)

×
x