Presentation is loading. Please wait.

Presentation is loading. Please wait.

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

Similar presentations


Presentation on theme: "DEV 321 Understanding and Using Advanced C++ Template Features and Topics on ISO C++ Scott Currie Program Manager Visual C++ Microsoft Corporation."— Presentation transcript:

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

2 [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

3 [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

4 Agenda Why you should care about conformance A 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) Summary Where to find out more Q & A

5 Agenda Why you should care about conformance A 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) Summary Where to find out more Q & A

6 Why you should care about conformance Library writers Use it daily for PTS and other features The rest of us Can use some techniques directly Library consumption has to work Anyone who uses multiple compilers Easier porting across compilers Lower maintenance and fewer #ifdefs

7 Agenda Why you should care about conformance A 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) Summary Where to find out more Q & A

8 A look into the standard library The standard library provides some useful containers: // safer than C-style array std::vector v; // safer than C-style array // much more flexible, too std::list l; // much more flexible, too // pick a data structure… std::deque d; // pick a data structure… You can construct a container in many ways… // empty by default // 10 ints with value 0 // 10 ints with value 42 // make a copy of v1 vector v1; // empty by default vector v2( 10 ); // 10 ints with value 0 vector v3( 10, 42 ); // 10 ints with value 42 vector v4( v1 ); // make a copy of v1 …but not from another container? // a list of ints // error – but isn’t this a // reasonable thing to do? list l; // a list of ints vector v5( l ); // error – but isn’t this a // reasonable thing to do?

9 Constructing from an iterator range To make this possible, the standard library containers can all be constructed also from an iterator range: // a list of ints // ok – aha! list l; // a list of ints vector v5( l.begin(), l.end() ); // ok – aha! Pointers are iterators too, so construct from an array… // or, strictly: &a[0], &a[ sizeof(a)/sizeof(int) ] int a[] = { 3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, 9, 8 }; vector v6( a, a+14 ); // or, strictly: &a[0], &a[ sizeof(a)/sizeof(int) ] … or even from the console using istream_iterators: vector v( istream_iterator ( cin ), (istream_iterator ()) ); sort( v.begin(), v.end() ); copy( v.begin(), v.end(), ostream_iterator out( cout, " " ) );

10 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 vector { template vector( InputIterator first, InputIterator last /*...*/ ); //... much more stuff... //... much more stuff... }; } Constructor templates

11 Of course, there’s more to member template functions than just constructors Templated assignment operators Templated accessor functions Templated conversions etc. Member templates now all work correctly in VC These examples all worked in VC too VC could not reliably handle any of this VC++ and member templates

12 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

13 Agenda Why you should care about conformance A 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) Summary Where to find out more Q & A

14 Here’s that fundamental tool again: /*... lots of stuff... */ namespace std { template > class vector { /*... lots of stuff... */ }; } You can specialize vector for your own types: /*... */ class MyType { /*... */ }; // explicit specialization // for T == MyType /* … lots of stuff … */ namespace std { template<> // explicit specialization class vector // for T == MyType { /* … lots of stuff … */ }; } Note: The above is a complete specialization (we know exactly what all the template arguments are) A look at std::vector

15 But what if your type is itself also a template? /*... */ template class MyType { /*... */ }; // explicit specialization??? // for T == ??? /* … lots of stuff … */ namespace std { template<>// explicit specialization??? class vector // for T == ??? { /* … 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: // partial specialization // for MyType /* … lots of stuff … */ namespace std { template // partial specialization class vector >// for MyType { /* … lots of stuff … */ }; } Why partial template specialization

16 Digression: Boost and Loki Boost Many excellent template libraries that work well with standard library Started by members of C++ Standards Committee Library Working Group Free, open source, peer reviewed Loki “A C++ library of designs, containing flexible implementations of common design patterns and idioms” Read Modern C++ Design

17 Digression: auto_ptr Be careful with std::auto_ptr Do not point auto_ptr at an array It only deletes. No delete[] Do not put an auto_ptr in a vector Can’t be indexed in a standard way Remember, auto_ptr uses single ownership Use Boost smart pointers instead shared_ptr Performs reference counting Using a shared_ptr to hold the results of every new will nearly eliminate the possibility of memory leaks

18 Here’s a fundamental tool from Loki, a list of types: template struct Typelist { typedef T Head; typedef U Tail; }; Sample usage (simplified by macros ): // Typelist TYPELIST_1(int) // Typelist // Typelist > TYPELIST_2(int, double) // Typelist > // etc. A look at Loki::Typelist

19 Calculate the length of a typelist: template struct Length; template <> struct Length { enum { value = 0 }; }; // partial specializ. template // partial specializ. struct Length > { enum { value = 1 + Length ::value }; }; Sample usage: // 3 Length ::value // 3 (Remember, this is all being done at compile time!) Why partial template specialization

20 Select the Nth type of a typelist : template struct TypeAt; // partial specializ. template // partial specializ. struct TypeAt, 0> { typedef Head Result; }; // again template // again struct TypeAt, i> { typedef typename TypeAt ::Result Result; }; Sample usage: // double TypeAt ::Result // double

21 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

22 Something more obviously(?) useful (& with TTPs!): template class Unit> class GenScatterHierarchy; /*…*/ template class Unit> class GenScatterHierarchy, Unit> : public GenScatterHierarchy, public GenScatterHierarchy { /*…*/ }; /*…*/ template class Unit> class GenScatterHierarchy : public Unit { /*…*/ }; /*…*/ template class Unit> class GenScatterHierarchy { /*…*/ }; This lets a class inherit from every type in a flexible list of types. Generics + OO = a boatload of power

23 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

24 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

25 PTS Summary Bread and butter of advanced library writer Provide basis of compile-time programming Two types of PTS Template template parameter Specify subset of multiple template parameters Not available for member templates They work in Visual C++.NET 2003 You should use to specialize library types for your own types and templated types Read Modern C++ Design!

26 Agenda Why you should care about conformance A 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) Summary Where to find out more Q & A

27 And now for a word from our standard… namespace NS { class T { }; void f(T); } NS::T parm; // no function f() seems to be in // scope -- is all lost? int main() { f(parm); // no function f() seems to be in } // scope -- is all lost? A motivating example

28 And now for a word from our standard… namespace NS { class T { }; void f(T); } NS::T parm; // OK: calls NS::f() int main() { f(parm); // 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

29 Q: Is this purely a notational convenience? What’s so hard about writing "NS::f(parm);" or "using NS::f;"? // gives std::operator #include // gives std::operator<<() for strings // ugh // "std::cout << hello;" is what we really want int main() { std::string hello = "Hello, world"; std::operator<<( std::cout, hello ); // ugh // "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?

30 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 does Koenig lookup for all functions, as required by the standard Useful example of what VC buys you? Actually, you have it in VC++.NET

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

32 More std::swap What if now we want a generic method? namespace NS { swap(tuple x, tuple y) {…} } tuple x; tuple y; template void swap_helper(T source, T target) { …. // Need Koenig lookup swap(source, target); // Need Koenig lookup …. } swap_helper > (x,y);

33 Koenig Summary Argument Dependent Lookup Be aware of operator example Understand what Koenig Lookup is all about Getting 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

34 Agenda Why you should care about conformance A 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) Summary Where to find out more Q & A

35 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 Loki (see etc. Know your power tools: partial specialization (see also Modern C++ Design) Koenig lookup (see also Exceptional C++) member template functions

36 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

37 Further Reading A. Alexandrescu. Modern C++ Design (Addison-Wesley, 2001) The official documentation for the Loki library. See also and my review of this book at: "Review of Modern C++ Design" (C/C++ Users Journal, 20(4), April 2002), 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)

38 Community Resources MS Community Sites List of newsgroups (Visual Tools and Languages -> C/C++) Attend a free chat or webcast C++ User Groups and Forums

39 evaluations evaluations

40 Agenda Why you should care about conformance A 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) Summary Where to find out more Q & A

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


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

Similar presentations


Ads by Google