SlideShare a Scribd company logo
1 of 4
Download to read offline
L
EARNING LATIN IN ORDER TO
learn French is a roundabout
route that might satisfy linguists,
historians and hobbyists with
time on their hands, but it’s unlikely to
appeal to the practically-minded. Nev-
ertheless, it’s still the approach taken
by many C++ books and courses. They
start by assuming or teaching C and C
idioms (with perhaps a basic garnish of
C++), and then add classes and other
language features according to taste.
Templates and the standard library are left
until the end – for some reason they are
often considered advanced topics simply
because they’re more recent.The informed
and more up-to-date thinking on this topic
reflects a quite different perspective1,2,3
.
The historical approach may well recall the way that
C++ evolved, and often the way that course and
book authors learned the language, but for C++
novices (the majority of whom are no longer C pro-
grammers), this is more a tour of the twisted back streets
of C++, with many important and interesting sights
overlooked. Learning C++ is no holiday, but it takes
longer this way than by treating it as a new language.
Programmers taught in the old way have less effec-
tive C++ skills than those taught in the new way, because
they are blind to the expressiveness that contempo-
rary idioms and the standard library offer them.
They are often taught C++ within a constrained, object-
oriented orthodoxy, ignoring the language’s sup-
port for other styles, such as generic programming.
These programmers are not to blame. It is typically
the fault of training companies, universities, authors,
publishers and colleagues who are still rooted in a former,
more mechanically minded C++ era.
The three ages of C++
C++ has evolved through three reasonably distinct
phases, each corresponding roughly with editions of
The C++ Programming Language4,5,6
. Each era can be
regarded as a separate language, with different features
and supporting different styles:
q Early C++: The first public incarnation of the
language formed part of a growing interest in the use
of object-oriented development in industry. Early
C++ was a minimal language, extending C with a
stronger type system, and the notion of classes with
public and private access, single inheritance and
operator overloading.
q Classic C++:This is the C++ that many long-time
C++ programmers know, and many new C++ pro-
grammers are still effectively being taught. It brought
abstract classes, multiple inheritance and further
refinements into the language. Classic C++ also
introduced templates and exceptions, although they
took longer to mature than other, more obviously
evolutionary features. Where templates are used,
it’s normally to articulate container classes and smart
pointers. Classic C++ saw the greatest proliferation
in dialects as it was in this period that the language
underwent standardisation. Changes ranged from the
trivial to the major, from bool to namespace, from the
proper incorporation of the standard C library to the
internationalisation overhaul of I/O. Many projects
still bear the scars of this portability interregnum.
62 APPLICATION DEVELOPMENT ADVISOR q www.appdevadvisor.com
Kevlin Henney is an
independent software
development consultant
and trainer.He can be
reached at
www.curbralan.com
EFFECTIVE C++
q Most C++ teaching is stuck in a bygone
era of thinking in C and then adding
objects.
q The majority of programmers now
learning C++ have never used C.
q Modern C++ should be taught as a
language in its own right.
q C++ supports many programming
styles, not just C and basic OO.
q Standard C++ should be taught at a
high level rather than a low level.
q Generic programming complements
traditional object-oriented
programming.
FACTS AT A GLANCE
Modern C++ is a more expressive, simpler language than C, and a language in
its own right, so why do so many people insist on teaching it historically?
Kevlin Henney appeals for a reform of the C++ education system
The miseducation of C++
q Modern C++: This is where we are now. The language was
standardised in 19987
, providing a fixed target for vendors and
a consolidation in thinking and practice. Exception safety is
now a well understood topic and the Standard Template Library
(STL) part of the library has introduced the full power of generic
programming to the language, raising templates from being
merely a way to express containers to an integral part of design
expression in C++. However, before it all starts sounding too good to
be true, compilers still need to do some catching up, and parts
of the library demonstrate the excesses possible through design
by committee. For instance, allocators, locales and strings all have
interfaces and semantics to die from, although strings at least have
the merit of being usable. Inside std::basic_string is a small class
struggling to get out.
These three eras aren’t separated by crisp boundaries. As with
any evolving language, each era fades into the next, and the seeds
of subsequent styles and demand for features are often sown in the
previous. For instance, although STL was made available in 1994
and then adopted into the draft standard, its full impact on
design style wasn’t felt and understood until later.
From bottom to top
There’s too much C++ being written. This isn’t about language
preferences, but a quantity judgement on the code being writ-
ten to express higher level designs. Much C++ suffers from
being low-level and repetitive. Whether it’s the manual management
of strings and arrays or the tedious transcription of similar
loops, there’s a lot of repetition and little abstraction of small house-
keeping tasks – in short, error-prone code and a failure to reuse
what exists already.
The sentiment has been growing for some time that teaching
C++ from scratch shouldn’t involve a descent into memory man-
agement to achieve simple tasks. Allan Vermeulen made the dis-
tinction that C++ was effectively two languages, one for building
components and the other for using them – Bottom C++ and Top
C++8
. Using an efficient library that wraps up low-level or com-
mon facilities is a different prospect from writing one, and each
does not require the same type or level of knowledge. This sepa-
ration of views between clients and suppliers has been preached
for a long time in OO thinking.
Text manipulation and good old-fashioned I/O have come
back into fashion, thanks to HTML, XML and ecommerce in general,
so it’s worth seeing the difference between introducing C++ with
and without the standard library in this context. Consider the com-
mon task of concatenating two given strings with a space between
them, such as a person’s first and last name. This task isn’t exactly
rocket science, but with a nuts and bolts view of C++, this looks
C-like and something like the following (assuming using namespace
std for brevity):
char *full_name(const char *first, const char *last)
{
const size_t length = strlen(first) + strlen(last) + 1;
char *result = new char[length + 1];
strcpy(result, first);
strcat(result, “ “);
strcat(result, last);
return result;
}
It’s possible to write this function in a single return statement,
but it’s unlikely anyone would thank you for it. Using this func-
tion also demands a certain amount of hoop jumping:
{
char *name = full_name(first, last);
... // perform tasks using name
delete[] name;
}
This isn’t exception safe, though, so perhaps the following:
{
char *name = full_name(first, last);
try
{
... // perform tasks using name
}
catch(...)
{
delete[] name;
throw; // repropagate to caller
}
}
Contrast this with the library-based approach:
string full_name(const string &first, const string &last)
{
return first + “ “ + last;
}
And in use, including exception safety:
{
string name = full_name(first, last);
... // perform tasks using name
}
It beats me why anyone would consider the first approach
better for learning, but it still seems to be popular. Is it a philos-
ophy of ‘no pain, no gain’? Perhaps ‘no pain, no pain’ is better. The
nitty-gritty internal workings can be learned more easily when you’re
comfortable with the usage – you don’t have to be able to design
a string class before you can use one. This is, after all, the whole
point of encapsulation.
For the same reason, templated container classes should be intro-
duced early on. Collections of data are so common in programs
that they can hardly be considered advanced, and therefore some-
thing to save until last. It’s far easier to explain that vector<int> can
be read as “vector of int”, where vector is a resizable array type, than
to explain all the details behind int *, the relationship between arrays
and pointers, and how to use new[] and delete[] correctly.
Hello, worlds
A modern approach to teaching C++ isn’t simply a concession to
using std::string and std::vector. It includes embracing generic
programming. Algorithmic abstraction in generic programming
goes beyond either the procedural view or the conventional
object-oriented view.
To get a feel for the difference, along with an appreciation of the
STL as more than just a container library, consider the task of print-
ing out a sequence of strings. Assume, first, that the source of strings
is fixed:
const char *const source[] =
{
“Mercury”, “Venus”, “Earth”, “Mars”,
“Jupiter”, “Saturn”, “Uranus”, “Neptune”, “Pluto”
};
APRIL 2001 63
EFFECTIVE C++
To print it, you can resort to the common-or-garden for loop:
for(std::size_t at = 0; at != 9; ++at)
std::cout << source[at] << std::endl;
Aside from some nasty hard-wiring of a constant, this doesn’t
seem to be crying out for improvement. Let’s move the goalposts
a little. What if the input sequence isn’t fixed at compile time? How
would you accommodate an arbitrary input set that could be piped
or typed in at runtime, such as “Mother Very Easily Makes Jam Sand-
wiches Using No Peanuts”, and process the sequence in some way
before printing it out? Without self-managing containers and
strings, this task turns into a delicate but long-winded demon-
stration of memory management minutiae. With them, it looks
much simpler:
std::vector<std::string> source;
std::string input;
while(std::cin >> input)
source.push_back(input);
... // process source
for(std::size_t at = 0; at != source.size(); ++at)
std::cout << source[at] << std::endl;
Let’s say that you want to alphabetically order the input.
Keeping things simple, let’s assume the English alphabet and an
ASCII-based character set. The standard multiset container uses
default less-than ordering, and default less-than ordering for a string
is just what we want. All the input is ordered as it comes in and,
because it’s a multiset rather than a set, duplicate strings will be
retained:
std::multiset<std::string> source;
std::string input;
while(std::cin >> input)
source.insert(input);
... // output
The subscript operator can’t be used for output because asso-
ciative containers, such as multiset, don’t support random access.
Iterators offer a means of decoupling the traversal of a container
from its underlying representation. STL iterators follow pointer
notation and semantics, representing an abstracted level of indi-
rection to each element:
... // input
std::multiset<std::string>::iterator at = source.begin();
while(at != source.end())
std::cout << *at++ << std::endl;
Although the condition and body of the loop are quite straight-
forward, there is a lot of syntactic baggage in the iterator decla-
ration. This load can be lightened a little with the aid of a
typedef, an oft-neglected feature in a class-based world:
typedef std::multiset<std::string> strings;
strings source;
std::string input;
while(std::cin >> input)
source.insert(input);
strings::iterator at = source.begin();
while(at != source.end())
std::cout << *at++ << std::endl;
This is about as far as you can go with the “STL is a container
library” point of view. Iterators are the key to opening up the rest
of the STL through its algorithms. Let’s switch back to using vector
so that we can accommodate general manipulation of ordering:
typedef std::vector<std::string> strings;
strings source;
std::string input;
while(std::cin >> input)
source.push_back(input);
... // process source
strings::iterator at = source.begin();
while(at != source.end())
std::cout << *at++ << std::endl;
If we want to sort the input, as with the previous example, we
can use the standard sort algorithm that operates on iterator ranges,
completely independent of the underlying container type:
std::sort(source.begin(), source.end());
An iterator range is defined as a half-open range that includes
its first element but excludes its last. The independence means
that you can use this algorithm with any range that supports ran-
dom access iterators, including raw C-style arrays and any of your
own application-specific containers.
If your sorting criteria are slightly different – say you want to
sort on string length – you can define a function that performs
the desired ordering comparison:
bool shorter(const std::string &lhs, const std::string &rhs)
{
return lhs.size() < rhs.size();
}
And then use it with std::sort:
std::sort(source.begin(), source.end(), shorter);
The concept of an iterator range isn’t restricted to containers.
You can also wrap I/O streams with iterators. To replace the input
loop, we can use the istream_iterator adaptor on std::cin:
std::istream_iterator<std::string> begin(std::cin), end;
std::copy(begin, end, std::back_inserter(source));
A defaulted istream_iterator represents the end of file. back_inserter
returns an adapted iterator that performs push_back on source for
every string copied. It is also possible to initialise source directly
from the input, without worrying about an intermediate copy-
ing stage. Dispensing with temporary variables and introducing
other typedefs, reverting to default sort ordering and abstracting
the output in terms of copying between iterator ranges, gives the
following script-like code:
typedef std::istream_iterator<std::string> in;
typedef std::ostream_iterator<std::string> out;
std::vector<std::string> source(in(std::cin), in());
std::sort(source.begin(), source.end());
std::copy(source.begin(), source.end(), out(std::cout, “n”));
Another change in requirements allows us to see a different
approach to tackling the output. Imagine you want the output
within quotes, so you can see any trailing spaces. The following
function prints a string out this way:
void quoted(const std::string &arg)
{
std::cout << ‘“’ << arg << ‘“’ << std::endl;
}
We can still abstract the loop by using one of the other stan-
dard algorithms, std::for_each, which applies its third argument
to each element in its given iterator range:
64 APPLICATION DEVELOPMENT ADVISOR q www.appdevadvisor.com
EFFECTIVE C++
std::for_each(source.begin(), source.end(), quoted);
What if we wish to parameterise the function so it can take streams
other than std::cout, such as a named file? std::for_each expects to
execute its third argument as a unary function, so we don’t have
the available bandwidth to introduce another argument. How-
ever, we can define simple, lightweight classes whose instances,
to all intents and purposes, behave like functions:
class quoted
{
public:
quoted(std::ostream &chosen_out)
: out(chosen_out)
{
}
void operator()(const std::string &arg)
{
out << ‘“’ << arg << ‘“’ << std::endl;
}
private:
std::ostream &out;
};
Function objects can retain individual state, such as the chosen
output stream, but still execute using the conventional function
call syntax. This allows them to slot right into many standard
algorithms:
std::for_each(source.begin(), source.end(), quoted(cout));
The quoted class seems to be quite useful, and possibly some-
thing you might want to reuse in another context. However, it
is currently tied to std::string. You might wish to use it with other
string types, numbers or your own application-specific classes. It’s
tempting to make the whole class a template:
template<typename argument_type>
class quoted
{
public:
quoted(std::ostream &chosen_out = std::cout)
: out(chosen_out)
{
}
void operator()(const argument_type &arg)
{
out << ‘“’ << arg << ‘“’ << std::endl;
}
private:
std::ostream &out;
};
But this makes it a little more awkward to use:
std::for_each(
source.begin(), source.end(),
quoted<std::string>());
In truth, the only feature that is dependent on the argument
type is operator() itself. A member template can capture this
variability:
class quoted
{
public:
quoted(std::ostream &chosen_out = std::cout)
: out(chosen_out)
{
}
template<typename argument_type>
void operator()(const argument_type &arg)
{
out << ‘“’ << arg << ‘“’ << std::endl;
}
private:
std::ostream &out;
};
Leaving the usage as before:
std::for_each(source.begin(), source.end(), quoted());
A new way of learning
If you’re unfamiliar with generic programming, this idiomatic
approach may look daunting. However, it is just that – a lack of
familiarity. Much language teaching is simply how to write pro-
cedural code in different languages in different styles. For C++,
such teaching can be characterised as how to write procedural code
with curly brackets, pointers and objects. Generic program-
ming is different from the procedural model of OO in that it
embraces a more value-based, functional programming style
that is practical and efficient. (In execution, it can be faster
than C.) The code we have just developed isn’t necessarily some-
thing you would hit a programmer with at the beginning of a course
or a book, but something to work towards – from loops for novices
to loops for practitioners.
C++ is by no means a trivial language, but modern C++ offers
a different set of features and styles from its earlier incarna-
tions, supporting simpler and more expressive idioms. Rather than
learning it historically as a class-based extension of C, it can be
understood directly and effectively as a quite distinct language.
It is far more compelling to teach the language by means of evolv-
ing designs – a set of differences, each of which demonstrates par-
ticular features and techniques – than through a set of differences
from C. Many programmers, and therefore many companies, are
quite simply missing out on a more effective set of skills by
being taught the wrong language.
So, next time you’re looking – for yourself or others – for a course
or book that purports to teach C++, look to see when strings and
simple container use are introduced. If it’s over a quarter of the
way through, be suspicious. If it’s over halfway through, don’t touch
it, except for morbid or historical interest. s
References
1. Stanley B Lippman, Essential C++, Addison-Wesley, 2000
2. Andrew Koenig and Barbara E Moo, Accelerated C++,
Addison-Wesley, 2000
3. Bjarne Stroustrup, Adding Classes to the C Language: An
Exercise in Language Evolution, Software – Practice and
Experience, Volume 13, Wiley, 1983
4. Bjarne Stroustrup, The C++ Programming Language,
Addison-Wesley, 1986
5. Bjarne Stroustrup, The C++ Programming Language,
Second edition, Addison-Wesley, 1991
6. Bjarne Stroustrup, The C++ Programming Language, Third
edition, Addison-Wesley, 1997
7. International Standard: Programming Language – C++,
ISO/IEC 14882:1998(E), 1998
8. Allan Vermeulen, Top C++, Object Magazine, SIGS,
June 1996
APRIL 2001 65
EFFECTIVE C++

More Related Content

What's hot

Introduction to c programming language
Introduction to c programming languageIntroduction to c programming language
Introduction to c programming languagesanjay joshi
 
Stringing Things Along
Stringing Things AlongStringing Things Along
Stringing Things AlongKevlin Henney
 
Std 10 Chapter 10 Introduction to C Language Important MCQs
Std 10 Chapter 10 Introduction to C Language Important MCQsStd 10 Chapter 10 Introduction to C Language Important MCQs
Std 10 Chapter 10 Introduction to C Language Important MCQsNuzhat Memon
 
Object-Oriented Programming in Modern C++. Borislav Stanimirov. CoreHard Spri...
Object-Oriented Programming in Modern C++. Borislav Stanimirov. CoreHard Spri...Object-Oriented Programming in Modern C++. Borislav Stanimirov. CoreHard Spri...
Object-Oriented Programming in Modern C++. Borislav Stanimirov. CoreHard Spri...corehard_by
 
C notes by m v b reddy(gitam)imp notes all units notes 5 unit order
C notes by m v b  reddy(gitam)imp  notes  all units notes  5 unit orderC notes by m v b  reddy(gitam)imp  notes  all units notes  5 unit order
C notes by m v b reddy(gitam)imp notes all units notes 5 unit orderMalikireddy Bramhananda Reddy
 
An Introduction To C++Templates
An Introduction To C++TemplatesAn Introduction To C++Templates
An Introduction To C++TemplatesGanesh Samarthyam
 

What's hot (12)

Introduction to c programming language
Introduction to c programming languageIntroduction to c programming language
Introduction to c programming language
 
Stringing Things Along
Stringing Things AlongStringing Things Along
Stringing Things Along
 
Std 10 Chapter 10 Introduction to C Language Important MCQs
Std 10 Chapter 10 Introduction to C Language Important MCQsStd 10 Chapter 10 Introduction to C Language Important MCQs
Std 10 Chapter 10 Introduction to C Language Important MCQs
 
Scoping
ScopingScoping
Scoping
 
Object-Oriented Programming in Modern C++. Borislav Stanimirov. CoreHard Spri...
Object-Oriented Programming in Modern C++. Borislav Stanimirov. CoreHard Spri...Object-Oriented Programming in Modern C++. Borislav Stanimirov. CoreHard Spri...
Object-Oriented Programming in Modern C++. Borislav Stanimirov. CoreHard Spri...
 
Ruby
RubyRuby
Ruby
 
C language
C languageC language
C language
 
C language part 1
C language part  1C language part  1
C language part 1
 
Mukesh
MukeshMukesh
Mukesh
 
C notes by m v b reddy(gitam)imp notes all units notes 5 unit order
C notes by m v b  reddy(gitam)imp  notes  all units notes  5 unit orderC notes by m v b  reddy(gitam)imp  notes  all units notes  5 unit order
C notes by m v b reddy(gitam)imp notes all units notes 5 unit order
 
An Introduction To C++Templates
An Introduction To C++TemplatesAn Introduction To C++Templates
An Introduction To C++Templates
 
88 c-programs
88 c-programs88 c-programs
88 c-programs
 

Viewers also liked

سبك زندگي سالم در دوران بارداري
سبك زندگي سالم در دوران بارداريسبك زندگي سالم در دوران بارداري
سبك زندگي سالم در دوران بارداريdigidanesh
 
Trust on LinkedIn | Why do people stop using LinkedIn?
Trust on LinkedIn | Why do people stop using LinkedIn?Trust on LinkedIn | Why do people stop using LinkedIn?
Trust on LinkedIn | Why do people stop using LinkedIn?Aoran Yang
 
2015 crisis management insight
2015 crisis management insight2015 crisis management insight
2015 crisis management insightDong Hyun Song
 
Discourse analysis and phonology chapter 4
Discourse analysis and phonology chapter 4Discourse analysis and phonology chapter 4
Discourse analysis and phonology chapter 4Kaikka Kaikka
 
바구니짜기 고서 - 전자북
바구니짜기 고서 - 전자북바구니짜기 고서 - 전자북
바구니짜기 고서 - 전자북Seongwon Kim
 
DYSLEXIC TEENAGER WINS INTERNATIONAL IT AWARD -  The Times Of India
DYSLEXIC TEENAGER WINS INTERNATIONAL IT AWARD - 	The Times Of India DYSLEXIC TEENAGER WINS INTERNATIONAL IT AWARD - 	The Times Of India
DYSLEXIC TEENAGER WINS INTERNATIONAL IT AWARD -  The Times Of India Jason Fernandes
 

Viewers also liked (9)

Readme
ReadmeReadme
Readme
 
سبك زندگي سالم در دوران بارداري
سبك زندگي سالم در دوران بارداريسبك زندگي سالم در دوران بارداري
سبك زندگي سالم در دوران بارداري
 
Certificates
CertificatesCertificates
Certificates
 
Trust on LinkedIn | Why do people stop using LinkedIn?
Trust on LinkedIn | Why do people stop using LinkedIn?Trust on LinkedIn | Why do people stop using LinkedIn?
Trust on LinkedIn | Why do people stop using LinkedIn?
 
2015 crisis management insight
2015 crisis management insight2015 crisis management insight
2015 crisis management insight
 
EX CERIFICATE
EX CERIFICATEEX CERIFICATE
EX CERIFICATE
 
Discourse analysis and phonology chapter 4
Discourse analysis and phonology chapter 4Discourse analysis and phonology chapter 4
Discourse analysis and phonology chapter 4
 
바구니짜기 고서 - 전자북
바구니짜기 고서 - 전자북바구니짜기 고서 - 전자북
바구니짜기 고서 - 전자북
 
DYSLEXIC TEENAGER WINS INTERNATIONAL IT AWARD -  The Times Of India
DYSLEXIC TEENAGER WINS INTERNATIONAL IT AWARD - 	The Times Of India DYSLEXIC TEENAGER WINS INTERNATIONAL IT AWARD - 	The Times Of India
DYSLEXIC TEENAGER WINS INTERNATIONAL IT AWARD -  The Times Of India
 

Similar to The Miseducation of C++

C++ vs C#
C++ vs C#C++ vs C#
C++ vs C#sudipv
 
Oops concepts in c++ documentation
Oops concepts in c++ documentationOops concepts in c++ documentation
Oops concepts in c++ documentationfarouq umar
 
Migrating From Cpp To C Sharp
Migrating From Cpp To C SharpMigrating From Cpp To C Sharp
Migrating From Cpp To C SharpGanesh Samarthyam
 
object oriented programming language fundamentals
object oriented programming language fundamentalsobject oriented programming language fundamentals
object oriented programming language fundamentalsChaithraCSHirematt
 
Object oriented programming c++
Object oriented programming c++Object oriented programming c++
Object oriented programming c++Ankur Pandey
 
C++programing
C++programingC++programing
C++programingrmvvr143
 
(Data structures) programming and problem solving
(Data structures) programming and problem solving(Data structures) programming and problem solving
(Data structures) programming and problem solvingShishir Roy
 
Intro. to prog. c++
Intro. to prog. c++Intro. to prog. c++
Intro. to prog. c++KurdGul
 
C++ In One Day_Nho Vĩnh Share
C++ In One Day_Nho Vĩnh ShareC++ In One Day_Nho Vĩnh Share
C++ In One Day_Nho Vĩnh ShareNho Vĩnh
 
6 Week C++ Language Training In Ambala
6 Week C++ Language Training In Ambala6 Week C++ Language Training In Ambala
6 Week C++ Language Training In AmbalaBatra Computer Centre
 

Similar to The Miseducation of C++ (20)

C++ vs C#
C++ vs C#C++ vs C#
C++ vs C#
 
Oops concepts in c++ documentation
Oops concepts in c++ documentationOops concepts in c++ documentation
Oops concepts in c++ documentation
 
Migrating From Cpp To C Sharp
Migrating From Cpp To C SharpMigrating From Cpp To C Sharp
Migrating From Cpp To C Sharp
 
object oriented programming language fundamentals
object oriented programming language fundamentalsobject oriented programming language fundamentals
object oriented programming language fundamentals
 
History of c++
History of c++History of c++
History of c++
 
Object oriented programming c++
Object oriented programming c++Object oriented programming c++
Object oriented programming c++
 
History of c++
History of c++ History of c++
History of c++
 
ewili13_submission_14
ewili13_submission_14ewili13_submission_14
ewili13_submission_14
 
C++programing
C++programingC++programing
C++programing
 
C++programing
C++programingC++programing
C++programing
 
C c#
C c#C c#
C c#
 
(Data structures) programming and problem solving
(Data structures) programming and problem solving(Data structures) programming and problem solving
(Data structures) programming and problem solving
 
Programming and problem solving with c++, 3rd edition
Programming and problem solving with c++, 3rd editionProgramming and problem solving with c++, 3rd edition
Programming and problem solving with c++, 3rd edition
 
Modern c
Modern cModern c
Modern c
 
Intro. to prog. c++
Intro. to prog. c++Intro. to prog. c++
Intro. to prog. c++
 
Highly Strung
Highly StrungHighly Strung
Highly Strung
 
C vs c++
C vs c++C vs c++
C vs c++
 
presentation on C++ basics by prince kumar kushwaha
presentation on C++ basics by prince kumar kushwahapresentation on C++ basics by prince kumar kushwaha
presentation on C++ basics by prince kumar kushwaha
 
C++ In One Day_Nho Vĩnh Share
C++ In One Day_Nho Vĩnh ShareC++ In One Day_Nho Vĩnh Share
C++ In One Day_Nho Vĩnh Share
 
6 Week C++ Language Training In Ambala
6 Week C++ Language Training In Ambala6 Week C++ Language Training In Ambala
6 Week C++ Language Training In Ambala
 

More from Kevlin Henney

The Case for Technical Excellence
The Case for Technical ExcellenceThe Case for Technical Excellence
The Case for Technical ExcellenceKevlin Henney
 
Empirical Development
Empirical DevelopmentEmpirical Development
Empirical DevelopmentKevlin Henney
 
Lambda? You Keep Using that Letter
Lambda? You Keep Using that LetterLambda? You Keep Using that Letter
Lambda? You Keep Using that LetterKevlin Henney
 
Lambda? You Keep Using that Letter
Lambda? You Keep Using that LetterLambda? You Keep Using that Letter
Lambda? You Keep Using that LetterKevlin Henney
 
Solid Deconstruction
Solid DeconstructionSolid Deconstruction
Solid DeconstructionKevlin Henney
 
Procedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went AwayProcedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went AwayKevlin Henney
 
Structure and Interpretation of Test Cases
Structure and Interpretation of Test CasesStructure and Interpretation of Test Cases
Structure and Interpretation of Test CasesKevlin Henney
 
Refactoring to Immutability
Refactoring to ImmutabilityRefactoring to Immutability
Refactoring to ImmutabilityKevlin Henney
 
Turning Development Outside-In
Turning Development Outside-InTurning Development Outside-In
Turning Development Outside-InKevlin Henney
 
Giving Code a Good Name
Giving Code a Good NameGiving Code a Good Name
Giving Code a Good NameKevlin Henney
 
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...Kevlin Henney
 
Thinking Outside the Synchronisation Quadrant
Thinking Outside the Synchronisation QuadrantThinking Outside the Synchronisation Quadrant
Thinking Outside the Synchronisation QuadrantKevlin Henney
 

More from Kevlin Henney (20)

Program with GUTs
Program with GUTsProgram with GUTs
Program with GUTs
 
The Case for Technical Excellence
The Case for Technical ExcellenceThe Case for Technical Excellence
The Case for Technical Excellence
 
Empirical Development
Empirical DevelopmentEmpirical Development
Empirical Development
 
Lambda? You Keep Using that Letter
Lambda? You Keep Using that LetterLambda? You Keep Using that Letter
Lambda? You Keep Using that Letter
 
Lambda? You Keep Using that Letter
Lambda? You Keep Using that LetterLambda? You Keep Using that Letter
Lambda? You Keep Using that Letter
 
Solid Deconstruction
Solid DeconstructionSolid Deconstruction
Solid Deconstruction
 
Get Kata
Get KataGet Kata
Get Kata
 
Procedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went AwayProcedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went Away
 
Structure and Interpretation of Test Cases
Structure and Interpretation of Test CasesStructure and Interpretation of Test Cases
Structure and Interpretation of Test Cases
 
Agility ≠ Speed
Agility ≠ SpeedAgility ≠ Speed
Agility ≠ Speed
 
Refactoring to Immutability
Refactoring to ImmutabilityRefactoring to Immutability
Refactoring to Immutability
 
Old Is the New New
Old Is the New NewOld Is the New New
Old Is the New New
 
Turning Development Outside-In
Turning Development Outside-InTurning Development Outside-In
Turning Development Outside-In
 
Giving Code a Good Name
Giving Code a Good NameGiving Code a Good Name
Giving Code a Good Name
 
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
 
Thinking Outside the Synchronisation Quadrant
Thinking Outside the Synchronisation QuadrantThinking Outside the Synchronisation Quadrant
Thinking Outside the Synchronisation Quadrant
 
Code as Risk
Code as RiskCode as Risk
Code as Risk
 
Software Is Details
Software Is DetailsSoftware Is Details
Software Is Details
 
Game of Sprints
Game of SprintsGame of Sprints
Game of Sprints
 
Good Code
Good CodeGood Code
Good Code
 

Recently uploaded

ManageIQ - Sprint 236 Review - Slide Deck
ManageIQ - Sprint 236 Review - Slide DeckManageIQ - Sprint 236 Review - Slide Deck
ManageIQ - Sprint 236 Review - Slide DeckManageIQ
 
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park %in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park masabamasaba
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfkalichargn70th171
 
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...Jittipong Loespradit
 
Sector 18, Noida Call girls :8448380779 Model Escorts | 100% verified
Sector 18, Noida Call girls :8448380779 Model Escorts | 100% verifiedSector 18, Noida Call girls :8448380779 Model Escorts | 100% verified
Sector 18, Noida Call girls :8448380779 Model Escorts | 100% verifiedDelhi Call girls
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrandmasabamasaba
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfonteinmasabamasaba
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...ICS
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension AidPhilip Schwarz
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsAlberto González Trastoy
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsArshad QA
 
The Top App Development Trends Shaping the Industry in 2024-25 .pdf
The Top App Development Trends Shaping the Industry in 2024-25 .pdfThe Top App Development Trends Shaping the Industry in 2024-25 .pdf
The Top App Development Trends Shaping the Industry in 2024-25 .pdfayushiqss
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisamasabamasaba
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplatePresentation.STUDIO
 
BUS PASS MANGEMENT SYSTEM USING PHP.pptx
BUS PASS MANGEMENT SYSTEM USING PHP.pptxBUS PASS MANGEMENT SYSTEM USING PHP.pptx
BUS PASS MANGEMENT SYSTEM USING PHP.pptxalwaysnagaraju26
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesVictorSzoltysek
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...Shane Coughlan
 
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionIntroducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionOnePlan Solutions
 

Recently uploaded (20)

ManageIQ - Sprint 236 Review - Slide Deck
ManageIQ - Sprint 236 Review - Slide DeckManageIQ - Sprint 236 Review - Slide Deck
ManageIQ - Sprint 236 Review - Slide Deck
 
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park %in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
Sector 18, Noida Call girls :8448380779 Model Escorts | 100% verified
Sector 18, Noida Call girls :8448380779 Model Escorts | 100% verifiedSector 18, Noida Call girls :8448380779 Model Escorts | 100% verified
Sector 18, Noida Call girls :8448380779 Model Escorts | 100% verified
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
The Top App Development Trends Shaping the Industry in 2024-25 .pdf
The Top App Development Trends Shaping the Industry in 2024-25 .pdfThe Top App Development Trends Shaping the Industry in 2024-25 .pdf
The Top App Development Trends Shaping the Industry in 2024-25 .pdf
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation Template
 
BUS PASS MANGEMENT SYSTEM USING PHP.pptx
BUS PASS MANGEMENT SYSTEM USING PHP.pptxBUS PASS MANGEMENT SYSTEM USING PHP.pptx
BUS PASS MANGEMENT SYSTEM USING PHP.pptx
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
 
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionIntroducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
 

The Miseducation of C++

  • 1. L EARNING LATIN IN ORDER TO learn French is a roundabout route that might satisfy linguists, historians and hobbyists with time on their hands, but it’s unlikely to appeal to the practically-minded. Nev- ertheless, it’s still the approach taken by many C++ books and courses. They start by assuming or teaching C and C idioms (with perhaps a basic garnish of C++), and then add classes and other language features according to taste. Templates and the standard library are left until the end – for some reason they are often considered advanced topics simply because they’re more recent.The informed and more up-to-date thinking on this topic reflects a quite different perspective1,2,3 . The historical approach may well recall the way that C++ evolved, and often the way that course and book authors learned the language, but for C++ novices (the majority of whom are no longer C pro- grammers), this is more a tour of the twisted back streets of C++, with many important and interesting sights overlooked. Learning C++ is no holiday, but it takes longer this way than by treating it as a new language. Programmers taught in the old way have less effec- tive C++ skills than those taught in the new way, because they are blind to the expressiveness that contempo- rary idioms and the standard library offer them. They are often taught C++ within a constrained, object- oriented orthodoxy, ignoring the language’s sup- port for other styles, such as generic programming. These programmers are not to blame. It is typically the fault of training companies, universities, authors, publishers and colleagues who are still rooted in a former, more mechanically minded C++ era. The three ages of C++ C++ has evolved through three reasonably distinct phases, each corresponding roughly with editions of The C++ Programming Language4,5,6 . Each era can be regarded as a separate language, with different features and supporting different styles: q Early C++: The first public incarnation of the language formed part of a growing interest in the use of object-oriented development in industry. Early C++ was a minimal language, extending C with a stronger type system, and the notion of classes with public and private access, single inheritance and operator overloading. q Classic C++:This is the C++ that many long-time C++ programmers know, and many new C++ pro- grammers are still effectively being taught. It brought abstract classes, multiple inheritance and further refinements into the language. Classic C++ also introduced templates and exceptions, although they took longer to mature than other, more obviously evolutionary features. Where templates are used, it’s normally to articulate container classes and smart pointers. Classic C++ saw the greatest proliferation in dialects as it was in this period that the language underwent standardisation. Changes ranged from the trivial to the major, from bool to namespace, from the proper incorporation of the standard C library to the internationalisation overhaul of I/O. Many projects still bear the scars of this portability interregnum. 62 APPLICATION DEVELOPMENT ADVISOR q www.appdevadvisor.com Kevlin Henney is an independent software development consultant and trainer.He can be reached at www.curbralan.com EFFECTIVE C++ q Most C++ teaching is stuck in a bygone era of thinking in C and then adding objects. q The majority of programmers now learning C++ have never used C. q Modern C++ should be taught as a language in its own right. q C++ supports many programming styles, not just C and basic OO. q Standard C++ should be taught at a high level rather than a low level. q Generic programming complements traditional object-oriented programming. FACTS AT A GLANCE Modern C++ is a more expressive, simpler language than C, and a language in its own right, so why do so many people insist on teaching it historically? Kevlin Henney appeals for a reform of the C++ education system The miseducation of C++
  • 2. q Modern C++: This is where we are now. The language was standardised in 19987 , providing a fixed target for vendors and a consolidation in thinking and practice. Exception safety is now a well understood topic and the Standard Template Library (STL) part of the library has introduced the full power of generic programming to the language, raising templates from being merely a way to express containers to an integral part of design expression in C++. However, before it all starts sounding too good to be true, compilers still need to do some catching up, and parts of the library demonstrate the excesses possible through design by committee. For instance, allocators, locales and strings all have interfaces and semantics to die from, although strings at least have the merit of being usable. Inside std::basic_string is a small class struggling to get out. These three eras aren’t separated by crisp boundaries. As with any evolving language, each era fades into the next, and the seeds of subsequent styles and demand for features are often sown in the previous. For instance, although STL was made available in 1994 and then adopted into the draft standard, its full impact on design style wasn’t felt and understood until later. From bottom to top There’s too much C++ being written. This isn’t about language preferences, but a quantity judgement on the code being writ- ten to express higher level designs. Much C++ suffers from being low-level and repetitive. Whether it’s the manual management of strings and arrays or the tedious transcription of similar loops, there’s a lot of repetition and little abstraction of small house- keeping tasks – in short, error-prone code and a failure to reuse what exists already. The sentiment has been growing for some time that teaching C++ from scratch shouldn’t involve a descent into memory man- agement to achieve simple tasks. Allan Vermeulen made the dis- tinction that C++ was effectively two languages, one for building components and the other for using them – Bottom C++ and Top C++8 . Using an efficient library that wraps up low-level or com- mon facilities is a different prospect from writing one, and each does not require the same type or level of knowledge. This sepa- ration of views between clients and suppliers has been preached for a long time in OO thinking. Text manipulation and good old-fashioned I/O have come back into fashion, thanks to HTML, XML and ecommerce in general, so it’s worth seeing the difference between introducing C++ with and without the standard library in this context. Consider the com- mon task of concatenating two given strings with a space between them, such as a person’s first and last name. This task isn’t exactly rocket science, but with a nuts and bolts view of C++, this looks C-like and something like the following (assuming using namespace std for brevity): char *full_name(const char *first, const char *last) { const size_t length = strlen(first) + strlen(last) + 1; char *result = new char[length + 1]; strcpy(result, first); strcat(result, “ “); strcat(result, last); return result; } It’s possible to write this function in a single return statement, but it’s unlikely anyone would thank you for it. Using this func- tion also demands a certain amount of hoop jumping: { char *name = full_name(first, last); ... // perform tasks using name delete[] name; } This isn’t exception safe, though, so perhaps the following: { char *name = full_name(first, last); try { ... // perform tasks using name } catch(...) { delete[] name; throw; // repropagate to caller } } Contrast this with the library-based approach: string full_name(const string &first, const string &last) { return first + “ “ + last; } And in use, including exception safety: { string name = full_name(first, last); ... // perform tasks using name } It beats me why anyone would consider the first approach better for learning, but it still seems to be popular. Is it a philos- ophy of ‘no pain, no gain’? Perhaps ‘no pain, no pain’ is better. The nitty-gritty internal workings can be learned more easily when you’re comfortable with the usage – you don’t have to be able to design a string class before you can use one. This is, after all, the whole point of encapsulation. For the same reason, templated container classes should be intro- duced early on. Collections of data are so common in programs that they can hardly be considered advanced, and therefore some- thing to save until last. It’s far easier to explain that vector<int> can be read as “vector of int”, where vector is a resizable array type, than to explain all the details behind int *, the relationship between arrays and pointers, and how to use new[] and delete[] correctly. Hello, worlds A modern approach to teaching C++ isn’t simply a concession to using std::string and std::vector. It includes embracing generic programming. Algorithmic abstraction in generic programming goes beyond either the procedural view or the conventional object-oriented view. To get a feel for the difference, along with an appreciation of the STL as more than just a container library, consider the task of print- ing out a sequence of strings. Assume, first, that the source of strings is fixed: const char *const source[] = { “Mercury”, “Venus”, “Earth”, “Mars”, “Jupiter”, “Saturn”, “Uranus”, “Neptune”, “Pluto” }; APRIL 2001 63 EFFECTIVE C++
  • 3. To print it, you can resort to the common-or-garden for loop: for(std::size_t at = 0; at != 9; ++at) std::cout << source[at] << std::endl; Aside from some nasty hard-wiring of a constant, this doesn’t seem to be crying out for improvement. Let’s move the goalposts a little. What if the input sequence isn’t fixed at compile time? How would you accommodate an arbitrary input set that could be piped or typed in at runtime, such as “Mother Very Easily Makes Jam Sand- wiches Using No Peanuts”, and process the sequence in some way before printing it out? Without self-managing containers and strings, this task turns into a delicate but long-winded demon- stration of memory management minutiae. With them, it looks much simpler: std::vector<std::string> source; std::string input; while(std::cin >> input) source.push_back(input); ... // process source for(std::size_t at = 0; at != source.size(); ++at) std::cout << source[at] << std::endl; Let’s say that you want to alphabetically order the input. Keeping things simple, let’s assume the English alphabet and an ASCII-based character set. The standard multiset container uses default less-than ordering, and default less-than ordering for a string is just what we want. All the input is ordered as it comes in and, because it’s a multiset rather than a set, duplicate strings will be retained: std::multiset<std::string> source; std::string input; while(std::cin >> input) source.insert(input); ... // output The subscript operator can’t be used for output because asso- ciative containers, such as multiset, don’t support random access. Iterators offer a means of decoupling the traversal of a container from its underlying representation. STL iterators follow pointer notation and semantics, representing an abstracted level of indi- rection to each element: ... // input std::multiset<std::string>::iterator at = source.begin(); while(at != source.end()) std::cout << *at++ << std::endl; Although the condition and body of the loop are quite straight- forward, there is a lot of syntactic baggage in the iterator decla- ration. This load can be lightened a little with the aid of a typedef, an oft-neglected feature in a class-based world: typedef std::multiset<std::string> strings; strings source; std::string input; while(std::cin >> input) source.insert(input); strings::iterator at = source.begin(); while(at != source.end()) std::cout << *at++ << std::endl; This is about as far as you can go with the “STL is a container library” point of view. Iterators are the key to opening up the rest of the STL through its algorithms. Let’s switch back to using vector so that we can accommodate general manipulation of ordering: typedef std::vector<std::string> strings; strings source; std::string input; while(std::cin >> input) source.push_back(input); ... // process source strings::iterator at = source.begin(); while(at != source.end()) std::cout << *at++ << std::endl; If we want to sort the input, as with the previous example, we can use the standard sort algorithm that operates on iterator ranges, completely independent of the underlying container type: std::sort(source.begin(), source.end()); An iterator range is defined as a half-open range that includes its first element but excludes its last. The independence means that you can use this algorithm with any range that supports ran- dom access iterators, including raw C-style arrays and any of your own application-specific containers. If your sorting criteria are slightly different – say you want to sort on string length – you can define a function that performs the desired ordering comparison: bool shorter(const std::string &lhs, const std::string &rhs) { return lhs.size() < rhs.size(); } And then use it with std::sort: std::sort(source.begin(), source.end(), shorter); The concept of an iterator range isn’t restricted to containers. You can also wrap I/O streams with iterators. To replace the input loop, we can use the istream_iterator adaptor on std::cin: std::istream_iterator<std::string> begin(std::cin), end; std::copy(begin, end, std::back_inserter(source)); A defaulted istream_iterator represents the end of file. back_inserter returns an adapted iterator that performs push_back on source for every string copied. It is also possible to initialise source directly from the input, without worrying about an intermediate copy- ing stage. Dispensing with temporary variables and introducing other typedefs, reverting to default sort ordering and abstracting the output in terms of copying between iterator ranges, gives the following script-like code: typedef std::istream_iterator<std::string> in; typedef std::ostream_iterator<std::string> out; std::vector<std::string> source(in(std::cin), in()); std::sort(source.begin(), source.end()); std::copy(source.begin(), source.end(), out(std::cout, “n”)); Another change in requirements allows us to see a different approach to tackling the output. Imagine you want the output within quotes, so you can see any trailing spaces. The following function prints a string out this way: void quoted(const std::string &arg) { std::cout << ‘“’ << arg << ‘“’ << std::endl; } We can still abstract the loop by using one of the other stan- dard algorithms, std::for_each, which applies its third argument to each element in its given iterator range: 64 APPLICATION DEVELOPMENT ADVISOR q www.appdevadvisor.com EFFECTIVE C++
  • 4. std::for_each(source.begin(), source.end(), quoted); What if we wish to parameterise the function so it can take streams other than std::cout, such as a named file? std::for_each expects to execute its third argument as a unary function, so we don’t have the available bandwidth to introduce another argument. How- ever, we can define simple, lightweight classes whose instances, to all intents and purposes, behave like functions: class quoted { public: quoted(std::ostream &chosen_out) : out(chosen_out) { } void operator()(const std::string &arg) { out << ‘“’ << arg << ‘“’ << std::endl; } private: std::ostream &out; }; Function objects can retain individual state, such as the chosen output stream, but still execute using the conventional function call syntax. This allows them to slot right into many standard algorithms: std::for_each(source.begin(), source.end(), quoted(cout)); The quoted class seems to be quite useful, and possibly some- thing you might want to reuse in another context. However, it is currently tied to std::string. You might wish to use it with other string types, numbers or your own application-specific classes. It’s tempting to make the whole class a template: template<typename argument_type> class quoted { public: quoted(std::ostream &chosen_out = std::cout) : out(chosen_out) { } void operator()(const argument_type &arg) { out << ‘“’ << arg << ‘“’ << std::endl; } private: std::ostream &out; }; But this makes it a little more awkward to use: std::for_each( source.begin(), source.end(), quoted<std::string>()); In truth, the only feature that is dependent on the argument type is operator() itself. A member template can capture this variability: class quoted { public: quoted(std::ostream &chosen_out = std::cout) : out(chosen_out) { } template<typename argument_type> void operator()(const argument_type &arg) { out << ‘“’ << arg << ‘“’ << std::endl; } private: std::ostream &out; }; Leaving the usage as before: std::for_each(source.begin(), source.end(), quoted()); A new way of learning If you’re unfamiliar with generic programming, this idiomatic approach may look daunting. However, it is just that – a lack of familiarity. Much language teaching is simply how to write pro- cedural code in different languages in different styles. For C++, such teaching can be characterised as how to write procedural code with curly brackets, pointers and objects. Generic program- ming is different from the procedural model of OO in that it embraces a more value-based, functional programming style that is practical and efficient. (In execution, it can be faster than C.) The code we have just developed isn’t necessarily some- thing you would hit a programmer with at the beginning of a course or a book, but something to work towards – from loops for novices to loops for practitioners. C++ is by no means a trivial language, but modern C++ offers a different set of features and styles from its earlier incarna- tions, supporting simpler and more expressive idioms. Rather than learning it historically as a class-based extension of C, it can be understood directly and effectively as a quite distinct language. It is far more compelling to teach the language by means of evolv- ing designs – a set of differences, each of which demonstrates par- ticular features and techniques – than through a set of differences from C. Many programmers, and therefore many companies, are quite simply missing out on a more effective set of skills by being taught the wrong language. So, next time you’re looking – for yourself or others – for a course or book that purports to teach C++, look to see when strings and simple container use are introduced. If it’s over a quarter of the way through, be suspicious. If it’s over halfway through, don’t touch it, except for morbid or historical interest. s References 1. Stanley B Lippman, Essential C++, Addison-Wesley, 2000 2. Andrew Koenig and Barbara E Moo, Accelerated C++, Addison-Wesley, 2000 3. Bjarne Stroustrup, Adding Classes to the C Language: An Exercise in Language Evolution, Software – Practice and Experience, Volume 13, Wiley, 1983 4. Bjarne Stroustrup, The C++ Programming Language, Addison-Wesley, 1986 5. Bjarne Stroustrup, The C++ Programming Language, Second edition, Addison-Wesley, 1991 6. Bjarne Stroustrup, The C++ Programming Language, Third edition, Addison-Wesley, 1997 7. International Standard: Programming Language – C++, ISO/IEC 14882:1998(E), 1998 8. Allan Vermeulen, Top C++, Object Magazine, SIGS, June 1996 APRIL 2001 65 EFFECTIVE C++