dev 321 understanding and using advanced c++ template features and topics on iso c++ scott currie...

41
DEV 321 Understanding and Using Advanced C++ Template Features and Topics on ISO C++ Scott Currie Program Manager Visual C++ Microsoft Corporation

Upload: penelope-donat

Post on 13-Dec-2015

226 views

Category:

Documents


5 download

TRANSCRIPT

Page 1: DEV 321 Understanding and Using Advanced C++ Template Features and Topics on ISO C++ Scott Currie Program Manager Visual C++ Microsoft Corporation

DEV 321Understanding and Using Advanced C++ Template Features and Topics on ISO C++

Scott CurrieProgram ManagerVisual C++Microsoft Corporation

Page 2: DEV 321 Understanding and Using Advanced C++ Template Features and Topics on ISO C++ Scott Currie Program Manager Visual C++ Microsoft Corporation

[After saying good things about VC++, which prompted chuckles from the audience]

"I may complain about Microsoft’s [C++] standards conformance, but it’s a good

compiler. If you can get your code through the front end, the back end will generate

amazingly efficient executables."

-- Scott Meyers, Boston, March 2002

A word from the field about standards conformance

Page 3: DEV 321 Understanding and Using Advanced C++ Template Features and Topics on ISO C++ Scott Currie Program Manager Visual C++ Microsoft Corporation

[After saying good things about VC++, which prompted chuckles from the audience]

"I may complain about Microsoft’s [C++] standards conformance, but it’s a good

compiler. If you can get your code through the front end, the back end will generate

amazingly efficient executables."

-- Scott Meyers, Boston, March 2002

A word from the field about standards conformance

Page 4: DEV 321 Understanding and Using Advanced C++ Template Features and Topics on ISO C++ Scott Currie Program Manager Visual C++ Microsoft Corporation

AgendaWhy you should care about conformanceA look at particular conformance areas:

Member templates(standard "iterator-range" constructors)Partial template specialization(specializing std::vector; Loki::TypeList)Koenig lookup (a.k.a. argument-dependent lookup, ADL)

SummaryWhere to find out moreQ & A

Page 5: DEV 321 Understanding and Using Advanced C++ Template Features and Topics on ISO C++ Scott Currie Program Manager Visual C++ Microsoft Corporation

AgendaWhy you should care about conformanceA look at particular conformance areas:

Member templates(standard "iterator-range" constructors)Partial template specialization (specializing std::vector; Loki::TypeList)Koenig lookup (a.k.a. argument-dependent lookup, ADL)

SummaryWhere to find out moreQ & A

Page 6: DEV 321 Understanding and Using Advanced C++ Template Features and Topics on ISO C++ Scott Currie Program Manager Visual C++ Microsoft Corporation

Why you should care about conformance

Library writersUse it daily for PTS and other features

The rest of usCan use some techniques directly

Library consumption has to work

Anyone who uses multiple compilersEasier porting across compilers

Lower maintenance and fewer #ifdefs

Page 7: DEV 321 Understanding and Using Advanced C++ Template Features and Topics on ISO C++ Scott Currie Program Manager Visual C++ Microsoft Corporation

AgendaWhy you should care about conformanceA look at particular conformance areas:

Member templates(standard "iterator-range" constructors)Partial template specialization (specializing std::vector; Loki::TypeList)Koenig lookup (a.k.a. argument-dependent lookup, ADL)

SummaryWhere to find out moreQ & A

Page 8: DEV 321 Understanding and Using Advanced C++ Template Features and Topics on ISO C++ Scott Currie Program Manager Visual C++ Microsoft Corporation

A look into the standard libraryThe standard library provides some useful containers:

std::vector<int> v; // safer than C-style array// safer than C-style arraystd::list<SomeUserType> l;// much more flexible, too// much more flexible, toostd::deque<bool> d; // pick a data structure…// pick a data structure…

You can construct a container in many ways…vector<int> v1; // empty by default// empty by defaultvector<int> v2( 10 ); // 10 ints with value 0// 10 ints with value 0vector<int> v3( 10, 42 ); // 10 ints with value 42// 10 ints with value 42vector<int> v4( v1 ); // make a copy of v1// make a copy of v1

…but not from another container?list<int> l; // a list of ints// a list of intsvector<int> v5( l ); // error – but isn’t this a// error – but isn’t this a

// reasonable thing to // reasonable thing to do?do?

Page 9: DEV 321 Understanding and Using Advanced C++ Template Features and Topics on ISO C++ Scott Currie Program Manager Visual C++ Microsoft Corporation

Constructing from an iterator rangeTo make this possible, the standard library containers can all be constructed also from an iterator range:

list<int> l; // a list of ints// a list of intsvector<int> v5( l.begin(), l.end() ); // ok – aha!// ok – aha!

Pointers are iterators too, so construct from an array…

int a[] = { 3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, 9, 8 };vector<int> v6( a, a+14 );

// or, strictly: &a[0], &a[ sizeof(a)/sizeof(int) ]// or, strictly: &a[0], &a[ sizeof(a)/sizeof(int) ]… or even from the console using istream_iterators:

vector<string> v( istream_iterator<string>( cin ), (istream_iterator<string>()) );

sort( v.begin(), v.end() );copy( v.begin(), v.end(),

ostream_iterator<string> out( cout, " " ) );

Page 10: DEV 321 Understanding and Using Advanced C++ Template Features and Topics on ISO C++ Scott Currie Program Manager Visual C++ Microsoft Corporation

There are infinitely many possible iterator types, so construction from an iterator range must be a member template to work with them all:namespace std { template <class T, class Allocator = allocator<T> > class vector { template <class InputIterator> vector( InputIterator first, InputIterator last /*...*//*...*/ );

// ... much more stuff ...// ... much more stuff ... };}

Constructor templates

Page 11: DEV 321 Understanding and Using Advanced C++ Template Features and Topics on ISO C++ Scott Currie Program Manager Visual C++ Microsoft Corporation

Of course, there’s more to member template functions than just constructors

Templated assignment operatorsTemplated accessor functionsTemplated conversionsetc.

Member templates now all work correctly in VC++ 2003These examples all worked in VC++ 2002 tooVC++ 6.0 could not reliably handle any of this

VC++ and member templates

Page 12: DEV 321 Understanding and Using Advanced C++ Template Features and Topics on ISO C++ Scott Currie Program Manager Visual C++ Microsoft Corporation

Limitations of member templates

Keep an eye open for a tie-back slide in the Partial Template Specialization section

A member function template shall not be virtual (14.5.2, p3)

Virtual dispatch does not allow compiler to do the right thing statically

So, the compiler emits a table of pointers for virtual members of each derived type (VTable)

This would cause VTable explosion with a single compiland

Impossible with multiple compilands unless a smart linker got involved

Page 13: DEV 321 Understanding and Using Advanced C++ Template Features and Topics on ISO C++ Scott Currie Program Manager Visual C++ Microsoft Corporation

AgendaWhy you should care about conformanceA look at particular conformance areas:

Member templates (standard "iterator-range" constructors)Partial template specialization (specializing std::vector; Loki::TypeList)Koenig lookup (a.k.a. argument-dependent lookup, ADL)

SummaryWhere to find out moreQ & A

Page 14: DEV 321 Understanding and Using Advanced C++ Template Features and Topics on ISO C++ Scott Currie Program Manager Visual C++ Microsoft Corporation

Here’s that fundamental tool again:namespace std { template <class T, class Allocator = allocator<T> > class vector { /* ... lots of stuff ... *//* ... lots of stuff ... */ };}

You can specialize vector for your own types:

class MyType { /* ... *//* ... */ };namespace std { template<> // explicit specialization// explicit specialization class vector<MyType> // for T == MyType// for T == MyType { /* … lots of stuff … *//* … lots of stuff … */ };}

Note: The above is a complete specialization (we know exactly what all the template arguments are)

A look at std::vector

Page 15: DEV 321 Understanding and Using Advanced C++ Template Features and Topics on ISO C++ Scott Currie Program Manager Visual C++ Microsoft Corporation

But what if your type is itself also a template?template<class T> class MyType { /* ... *//* ... */ };namespace std { template<> // explicit specialization???// explicit specialization??? class vector<???> // for T == ???// for T == ??? { /* … lots of stuff … *//* … lots of stuff … */ };}We couldn’t possibly write out all the complete specializations (even if we wanted to)Instead, we want a “partial” specialization – one that is still parameterized, but for a subset of types:namespace std { template<class T>// partial specialization// partial specialization class vector<MyType<T> > // for MyType<T>// for MyType<T> { /* … lots of stuff … *//* … lots of stuff … */ };}

Why partial template specialization

Page 16: DEV 321 Understanding and Using Advanced C++ Template Features and Topics on ISO C++ Scott Currie Program Manager Visual C++ Microsoft Corporation

Digression: Boost and LokiBoost

Many excellent template libraries that work well with standard libraryStarted by members of C++ Standards Committee Library Working GroupFree, open source, peer reviewedhttp://www.boost.org/

Loki“A C++ library of designs, containing flexible implementations of common design patterns and idioms”Read Modern C++ Designhttp://sourceforge.net/projects/loki-lib/

Page 17: DEV 321 Understanding and Using Advanced C++ Template Features and Topics on ISO C++ Scott Currie Program Manager Visual C++ Microsoft Corporation

Digression: auto_ptrBe careful with std::auto_ptr

Do not point auto_ptr at an arrayIt only deletes. No delete[]

Do not put an auto_ptr in a vectorCan’t be indexed in a standard way

Remember, auto_ptr uses single ownership

Use Boost smart pointers insteadshared_ptr

Performs reference counting

Using a shared_ptr to hold the results of every new will nearly eliminate the possibility of memory leaks

Page 18: DEV 321 Understanding and Using Advanced C++ Template Features and Topics on ISO C++ Scott Currie Program Manager Visual C++ Microsoft Corporation

Here’s a fundamental tool from Loki, a list of types:template <class T, class U>struct Typelist { typedef T Head; typedef U Tail;};

Sample usage (simplified by macros ):TYPELIST_1(int)

// Typelist<int, NullType>// Typelist<int, NullType>TYPELIST_2(int, double)

// Typelist<int, Typelist<double, NullType> >// Typelist<int, Typelist<double, NullType> >

// etc.// etc.

A look at Loki::Typelist

Page 19: DEV 321 Understanding and Using Advanced C++ Template Features and Topics on ISO C++ Scott Currie Program Manager Visual C++ Microsoft Corporation

Calculate the length of a typelist:template <class TList> struct Length;

template <> struct Length<NullType> { enum { value = 0 };};

template <class T, class U> // partial specializ.// partial specializ.struct Length< Typelist<T, U> > { enum { value = 1 + Length<U>::value };};

Sample usage:

Length< TYPELIST_3(int, double, bool) >::value // 3// 3

(Remember, this is all being done at compile time!)

Why partial template specialization

Page 20: DEV 321 Understanding and Using Advanced C++ Template Features and Topics on ISO C++ Scott Currie Program Manager Visual C++ Microsoft Corporation

Why partial template specialization

Select the Nth type of a typelist:template <class TList, unsigned index> struct TypeAt;

template <class Head, class Tail> // partial specializ.// partial specializ.struct TypeAt<Typelist<Head, Tail>, 0> { typedef Head Result;};

template <class Head, class Tail, unsigned int i> // again// againstruct TypeAt<Typelist<Head, Tail>, i> { typedef typename TypeAt<Tail, i - 1>::Result Result;};

Sample usage:TypeAt< TYPELIST_3(int, double, bool), 1>::Result

// double// double

Page 21: DEV 321 Understanding and Using Advanced C++ Template Features and Topics on ISO C++ Scott Currie Program Manager Visual C++ Microsoft Corporation

Other operations on typelists:Search: IndexOf<>Append: Append<>Erase: Erase<>Remove duplicates: NoDuplicates<>Replace: Replace<>Partial sort according to an inheritance hierarchy (really!): DerivedToFront<>

Every single one of these requires partial specialization (or "partial workarounds") because they’re defined recursively with a special case (or two) to end the recursion

Why partial template specialization

Page 22: DEV 321 Understanding and Using Advanced C++ Template Features and Topics on ISO C++ Scott Currie Program Manager Visual C++ Microsoft Corporation

Something more obviously(?) useful (& with TTPs!):template <class TList, template <class> class Unit>class GenScatterHierarchy;template <class T1, class T2, template<class> class Unit>class GenScatterHierarchy<Typelist<T1, T2>, Unit> : public GenScatterHierarchy<T1, Unit> , public GenScatterHierarchy<T2, Unit> { /*…*/ /*…*/ };template <class AtomicType, template <class> class Unit>class GenScatterHierarchy : public Unit<AtomicType> { /*…*//*…*/ };template <template <class> class Unit>class GenScatterHierarchy<NullType, Unit> { /*…*//*…*/ };

This lets a class inherit from every type in a flexible list of types.

Generics + OO = a boatload of power

Page 23: DEV 321 Understanding and Using Advanced C++ Template Features and Topics on ISO C++ Scott Currie Program Manager Visual C++ Microsoft Corporation

Member Templates

Here is the tie-back

Cannot be partially specialized

Only explicit specialization

How do we achieve similar functionality?Overloading

Provides very similar pattern matching

Code bloat

Page 24: DEV 321 Understanding and Using Advanced C++ Template Features and Topics on ISO C++ Scott Currie Program Manager Visual C++ Microsoft Corporation

Remember, this is all "executed" at compile time!

To quote Herb Sutter, about Modern C++ Design:

"… ‘can compiler XYZ compile Loki?’ is becoming something of an unofficial benchmark in compiler-writer circles. … Loki is written entirely in normal standard-conforming C++ — only more standard and more conforming, it turns out, than some compilers are yet quite ready to digest. Loki … uses templates so widely and heavily that it tears the tar and stresses the stuffing out of some current compilers. In fact, at the time the book was released [2001], no commercially available compiler could compile all of Loki correctly…"

A word about compiler-busting

Page 25: DEV 321 Understanding and Using Advanced C++ Template Features and Topics on ISO C++ Scott Currie Program Manager Visual C++ Microsoft Corporation

PTS Summary

Bread and butter of advanced library writerProvide basis of compile-time programmingTwo types of PTS

Template template parameterSpecify subset of multiple template parameters

Not available for member templatesThey work in Visual C++ .NET 2003You should use to specialize library types for your own types and templated typesRead Modern C++ Design!

Page 26: DEV 321 Understanding and Using Advanced C++ Template Features and Topics on ISO C++ Scott Currie Program Manager Visual C++ Microsoft Corporation

AgendaWhy you should care about conformanceA look at particular conformance areas:

Member templates (standard "iterator-range" constructors)Partial template specialization (specializing std::vector; Loki::TypeList)Koenig lookup (a.k.a. argument-dependent lookup, ADL)

SummaryWhere to find out moreQ & A

Page 27: DEV 321 Understanding and Using Advanced C++ Template Features and Topics on ISO C++ Scott Currie Program Manager Visual C++ Microsoft Corporation

And now for a word from our standard…namespace NS{ class T { }; void f(T);}

NS::T parm;

int main() { f(parm); // no function f() seems to be in// no function f() seems to be in} // scope -- is all lost?// scope -- is all lost?

A motivating example

Page 28: DEV 321 Understanding and Using Advanced C++ Template Features and Topics on ISO C++ Scott Currie Program Manager Visual C++ Microsoft Corporation

And now for a word from our standard…namespace NS{ class T { }; void f(T);}

NS::T parm;

int main() { f(parm); // OK: calls NS::f()// OK: calls NS::f()}

The parameter comes from namespace NS, therefore in addition to looking for candidate functions/functors in all the usual places, the compiler is required to also look in NS

A motivating example

Page 29: DEV 321 Understanding and Using Advanced C++ Template Features and Topics on ISO C++ Scott Currie Program Manager Visual C++ Microsoft Corporation

Q: Is this purely a notational convenience? What’s so hard about writing "NS::f(parm);" or "using NS::f;"?

#include <iostream>#include <string> // gives std::operator<<() for // gives std::operator<<() for stringsstringsint main() { std::string hello = "Hello, world"; std::operator<<( std::cout, hello ); // ugh// ugh // "std::cout << hello;" is what we really want // "std::cout << hello;" is what we really want}

It would be disgraceful if the programmer had to qualify this name, because either the operator couldn’t be used naturally, or the user would have to write "using std::operator<<;" (tedious) or "using namespace std;" (although I recommend the latter for other reasons…)

How important is it really?

Page 30: DEV 321 Understanding and Using Advanced C++ Template Features and Topics on ISO C++ Scott Currie Program Manager Visual C++ Microsoft Corporation

But VC++ (.NET) 2002 did Koenig lookup only for operators

Happens to be a very common case

Happens to speak directly to the foregoing example

VC++ 2003 does Koenig lookup for all functions, as required by the standard

Useful example of what VC++ 2003 buys you?

Actually, you have it in VC++ .NET

Page 31: DEV 321 Understanding and Using Advanced C++ Template Features and Topics on ISO C++ Scott Currie Program Manager Visual C++ Microsoft Corporation

Reimplementing std::swapBasics

namespace NS { swap(tuple x, tuple y) {…} tuple<int,int> x; tuple<int,int> y; … swap(x,y); // OK: calls NS::swap()// OK: calls NS::swap()}

What if swap is out of namespace?namespace NS { swap(tuple x, tuple y) {…}}tuple<int,int> x;tuple<int,int> y;….swap(x,y); // BAD: calls std::swap()// BAD: calls std::swap()NS::swap(x,y); // OK: calls NS::swap(), but annoying// OK: calls NS::swap(), but annoying

Page 32: DEV 321 Understanding and Using Advanced C++ Template Features and Topics on ISO C++ Scott Currie Program Manager Visual C++ Microsoft Corporation

More std::swapWhat if now we want a generic method?

namespace NS { swap(tuple x, tuple y) {…}}tuple<int,int> x;tuple<int,int> y;

template <class T>void swap_helper(T source, T target) { …. swap(source, target); // Need Koenig lookup// Need Koenig lookup ….}swap_helper <tuple <int,int> > (x,y);

Page 33: DEV 321 Understanding and Using Advanced C++ Template Features and Topics on ISO C++ Scott Currie Program Manager Visual C++ Microsoft Corporation

Koenig Summary

Argument Dependent Lookup

Be aware of operator example

Understand what Koenig Lookup is all aboutGetting around the lack of namespace passing ability to generic code

If you use namespaces, be careful about name collisions and the ordering behavior

If you use namespaces and generics, you will likely have to depend on this

Page 34: DEV 321 Understanding and Using Advanced C++ Template Features and Topics on ISO C++ Scott Currie Program Manager Visual C++ Microsoft Corporation

AgendaWhy you should care about conformanceA look at particular conformance areas:

Member templates (standard "iterator-range" constructors)Partial template specialization (specializing std::vector; Loki::TypeList)Koenig lookup (a.k.a. argument-dependent lookup, ADL)

SummaryWhere to find out moreQ & A

Page 35: DEV 321 Understanding and Using Advanced C++ Template Features and Topics on ISO C++ Scott Currie Program Manager Visual C++ Microsoft Corporation

Best practices (on any good compiler)

Know your community and the community libraries:

full STL (see also Effective STL)Standard gets revised, so stay up to date

Boost (see www.boost.org)

Loki (see www.moderncppdesign.com)

etc.

Know your power tools:partial specialization (see also Modern C++ Design)

Koenig lookup (see also Exceptional C++)

member template functions

Page 36: DEV 321 Understanding and Using Advanced C++ Template Features and Topics on ISO C++ Scott Currie Program Manager Visual C++ Microsoft Corporation

VC++ and you(r projects)

You now have one of the most standards-conforming implementations of one of the most powerful and flexible programming languages in the world

Use Standard C++ to your best advantage:"Explore, try, perform"

Don’t be afraid of making full use of advanced language features

Don’t be afraid of exploring and exploiting the full power of community libraries like Boost and Loki and MTL

Page 37: DEV 321 Understanding and Using Advanced C++ Template Features and Topics on ISO C++ Scott Currie Program Manager Visual C++ Microsoft Corporation

Further ReadingA. Alexandrescu. Modern C++ Design(Addison-Wesley, 2001)

The official documentation for the Loki library. See also www.mcppdesign.com and my review of this book at:

"Review of Modern C++ Design"(C/C++ Users Journal, 20(4), April 2002),www.gotw.ca/publications/mcd_review.htm

N. Josuttis. The C++ Standard Library (Addison-Wesley, 1999)

S. Meyers. Effective STL (Addison-Wesley, 2002)H. Sutter. Exceptional C++ and

More Exceptional C++ (Addison-Wesley, 2000 & 2002)

H. Sutter. Guru of the Week (www.gotw.ca)

Page 38: DEV 321 Understanding and Using Advanced C++ Template Features and Topics on ISO C++ Scott Currie Program Manager Visual C++ Microsoft Corporation

Community Resources

MS Community Siteshttp://msdn.microsoft.com/visualchttp://gotdotnet.com/team/cplusplus

List of newsgroupshttp://msdn.microsoft.com/newsgroups(Visual Tools and Languages -> C/C++)

Attend a free chat or webcasthttp://microsoft.com/communities/chats/default.mspxhttp://microsoft.com/usa/webcasts/default.asp

C++ User Groups and Forumshttp://www.mvps.org/vcfaqhttp://cplus.about.com/cs/visualchttp://www.accu.orghttp://www.codeguru.comhttp://www.codeproject.comhttp://www.devx.com/cplus/Door/7042

Page 39: DEV 321 Understanding and Using Advanced C++ Template Features and Topics on ISO C++ Scott Currie Program Manager Visual C++ Microsoft Corporation

evaluationsevaluations

Page 40: DEV 321 Understanding and Using Advanced C++ Template Features and Topics on ISO C++ Scott Currie Program Manager Visual C++ Microsoft Corporation

AgendaWhy you should care about conformanceA look at particular conformance areas:

Member templates (standard "iterator-range" constructors)Partial template specialization (specializing std::vector; Loki::TypeList)Koenig lookup (a.k.a. argument-dependent lookup, ADL)

SummaryWhere to find out moreQ & A

Page 41: DEV 321 Understanding and Using Advanced C++ Template Features and Topics on ISO C++ Scott Currie Program Manager Visual C++ Microsoft Corporation

© 2003 Microsoft Corporation. All rights reserved.© 2003 Microsoft Corporation. All rights reserved.This presentation is for informational purposes only. MICROSOFT MAKES NO WARRANTIES, EXPRESS OR IMPLIED, IN THIS SUMMARY.This presentation is for informational purposes only. MICROSOFT MAKES NO WARRANTIES, EXPRESS OR IMPLIED, IN THIS SUMMARY.