Overload 126 PDF

OVERLOAD
CONTENTS
OVERLOAD 126
April 2015
ISSN 1354-3172
Editor
Frances Buontempo
[email protected]
Overload is a publication of the ACCU
For details of the ACCU, our publications
and activities, visit the ACCU website:
www.accu.org
Advisors
Matthew Jones
[email protected]
Mikael Kilpeläinen
[email protected]
Steve Love
[email protected]
Chris Oldwood
[email protected]
Roger Orr
[email protected]
Jon Wakely
[email protected]
Anthony Williams
[email protected]
Advertising enquiries
[email protected]
Printing and distribution
Parchment (Oxford) Ltd
Cover art and design
Pete Goodliffe
[email protected]
Copy deadlines
All articles intended for publication in
Overload 127 should be submitted
by 1st May 2015 and those for
Overload 128 by 1st July 2015.
4 Non-Superfluous People: UX Specialists
Sergey Ignatchenko demonstrates why user
experience specialists are not superfluous.
9 Alternatives to Singletons and Global
Variables
Bob Schmidt summarises some alternatives to
singletons.
14 Resource Management with Explicit
Template Specializations
Pavel Frolov presents RAII with explicit template
specialisation.
19 Variadic and Variable Templates
Peter Sommerlad showcases the compile-time
possibilities Variadic and Variable templates offer.
23iterator_pair – a simple and useful
iterator adapter
Vladimir Grigoriev reminds us how to write an
iterator.
32Seeing the Wood for the Trees
Teedy Deigh takes an enterprising look at logs.
The ACCU
Copyrights and Trade Marks
The ACCU is an organisation of
programmers who care about
professionalism in programming. That is,
we care about writing good code, and
about writing it in a good way. We are
dedicated to raising the standard of
programming.
Some articles and other contributions use terms that are either registered trade marks or claimed
as such. The use of such terms is not intended to support nor disparage any trade mark claim.
On request we will withdraw all references to a specific trade mark and its owner.
The articles in this magazine have all
been written by ACCU members - by
programmers, for programmers - and
have been contributed free of charge.
By default, the copyright of all material published by ACCU is the exclusive property of the author.
By submitting material to ACCU for publication, an author is, by default, assumed to have granted
ACCU the right to publish and republish that material in any medium as they see fit. An author
of an article or column (not a letter or a review of software or a book) may explicitly offer single
(first serial) publication rights and thereby retain all other rights.
Except for licences granted to 1) Corporate Members to copy solely for internal distribution 2)
members to copy source code for use on their own computers, no material can be copied from
Overload without written permission from the copyright holder.
April 2015 | Overload | 1
EDITORIAL
FRANCES BUONTEMPO
Where was I?
Space and time are relative. Frances Buontempo
wonders whether this will wash as an excuse for
another lack of editorial.
Previously we almost wandered into the religious
realm, while considering fear, uncertainty and doubt
[FUD]. If we were to bring things round to a more
scientific perspective, we might find relativity leaves
us doubting where, or when, we actually are, though
I am getting ahead of myself. I realise I should bring
things back on track and finally embark on an editorial but what with one
thing and another I have been distracted yet again. Firstly, though perhaps
less significantly, I have started a new job so am in the process of learning
various new TLAs, eTLAs and TLs.1 Secondly, I have been drawn by a
recurring theme of late around telepresence, perhaps the ultimate spooky
action at a distance. Having just finished The peripheral by William
Gibson [Gibson], which concerns people remotely operating various
machines, from ‘peripherals’ which seem to be human sized dolls
designed for such purposes, through homunculi to a ‘wheelie-boy’ which
is a smart-phone on wheels. These allow people to interact across space,
and being a sci-fi book, across time as well. For many years it has been
possible to use a telephone to speak to someone a great distance away and
given newer technologies like video-phones, a move towards a physical
remote-presence seems like the next big thing.
I recently watched Kraftwerk: Pop Art [Kraftwerk], which fed into this
train of thought. For quite a long time now, photo-shoots have used their
robots instead of the band members. When performing, these robots
frequently take up residence on stage playing the instruments instead of
the people. This may seem odd, but clearly allows the music to continue,
and to an extent, the band to continue performing long after the initial
people are gone – a form of time travel. Other bands don’t physically exist,
for example The Gorillaz spring to mind [Gorillaz]. The audience is still
at the gig even if the band physically are not. And flipping it around, I own
DVDs of shows which I can then watch at any time, without being at the
actual venue and this can almost feel like having engaged with the
experience to an extent. Perhaps one day I will be able to operate a minidrone to remotely experience a concert. It does not always matter exactly
where or when you are.
It has been possible to operate a physical device remotely for some time
now. More recent examples include surgery and surgical simulators with
haptic feedback [LSRO], bomb disposal and fire-fighting robots
[SAFFiR] and unmanned space-crafts. Some of these operate in real time,
and others are more fire and forget. Simpler exemplars could be argued
to include a telephone or a television, perhaps via a remote control. Again,
spooky action at a distance. If haptics allow you to feel
something that is very far away or even
virtual, what other ‘tele’-types are possible?
Telesmell? Telesthesia? Telemetry?
Teleportation? How far can this remote
presence go? Would it be socially acceptable? It may be frowned upon to
dial into a team’s daily scrum meeting, but sometimes a team is distributed
across the globe, so it is sensible to do this. What if I sent in a mini-me
robot or wheelie-boy to a meeting instead of actually turning up? Is that
different to sending a secretary? Could the whole team ‘meet’ in a virtual
reality world to discuss things? Would this be easier than a phone
meeting? Do you need to interview a candidate face to face? Could you
get married via a phone conference? New technologies bring about new
social norms, where the previously unthinkable becomes par for the
course.
Many people in the industry work from home for a large percentage of
time nowadays, while others, perhaps in a business facing role, do so
almost never. Some people prefer to communicate directly, while others
will prefer emails or chat rooms. It will always be context dependant. If
someone is demonstrating a new API, I like to have some code snippets
in an email to refer back to rather than trying to frantically scribble notes
and listen at the same time. The method of communication can and must
depend on the circumstances. Having wondered if everyone needs to be
physically ‘there’ begs the question, where is ‘there’ anyway. How many
times have you looked round a meeting to see people staring at their smart
phones? If someone, say a politician, is physically present at a meeting,
but seemingly engaged in a game, say Candy Crush Saga [Mills], at least
in one sense they are not really at the meeting but elsewhere. If I am at
my desk on my PC but remoted to another machine, where am I? If I log
on as someone else, who am I? Of course, various machines will answer
‘whoami’ but where am I is clearly a harder question. If the machine I
remote to is a virtual machine, am I in the ‘Matrix’ – some form of nonphysical reality? And yet my body is still at my desk. I am in two places
at once.
Almost everyone has bemoaned the impossibility of actually being in two
places at once, even though we have all plainly touched on this possibility
without taking the full Candy Crush leap. Suppose for a moment I could
clone myself and genuinely be in two places at once. Then I would have
had the time to write Overload a proper editorial. Whatever your reason
for needing to be in two places at once, you might feel the need to
rendezvous with yourself at some point in space and time to synchronise.
This presupposes the clone is really a deep copy. A shallow copy would
rather defeat the purpose. The confusion of two individuals being the
same, identically, and in no way different, presumably being in the same
place at the same time, goes beyond the horror of memory leaks or double
deletes and breaks the laws of physics. Without harmonising or reintegrating between your many selves, at least one of you would in some
sense cease to be you. Would the synchronisation require a lock of time
1. Three letter acronyms, extended three letter acronyms and two letters
Frances Buontempo works at Bloomberg, has a BA in Maths + Philosophy, an MSc in Pure Maths and
a PhD technically in Chemical Engineering, but mainly programming and learning about AI and data
mining. She has been a programmer since the 90s, and learnt to program by reading the manual for her
Dad’s BBC model B machine. She can be contacted at [email protected].
2 | Overload | April 2015
FRANCES BUONTEMPO
EDITORIAL
or reality? That may prove tricky to implement. Even if it were possible,
time could pass while catching up with yourself, so it isn’t immediately
apparent that cloning yourself would be the time-saver we hoped for. As
with many applications that start life single-threaded, any attempt to save
time by introducing some concurrency may actually slow things down,
especially if you are using shared memory. A much simpler alternative is
to delegate the editorial writing, or whatever tasks you are currently
avoiding, to someone else and just hope for the best.
implant, which brings to mind various stories regarding Kevin ‘Captain
Cyborg’ Warwick:
Even if we keep things simple and try to just be in one place at one time,
things may not be straightforward. I mentioned relativity earlier. Though
we may feel we are taking things slowly and methodically, going nowhere
near the speed of light, precision regarding when and where we are often
matters. I saw a recent plea on Twitter to retweet a post by 10pm in order
to be in with a chance to win a book. First, I needed to know by 10pm on
which day, and furthermore, I needed to know which time-zone. Not
everyone is in the same place as you. Midday does not mean the same time
to everyone. Neither does early in the morning, though questions of sleepwake homeostasis and circadian biological clocks are beyond the scope of
my current meanderings. How long I have before 10pm is another matter
for discussion. Special relativity tells us about time dilation and length
contraction, “A clock in a moving frame will be seen to be running slow, or
‘dilated’” [Hyperphysics] Perhaps this is why deadlines don’t seem so close
until you are right on top of them. This might not be the best excuse to give
your manager for being late with a project, so use judiciously.
To me it is self-evident. The door would then open for anyone who
borrowed his jacket. Alternatively, if he left his jacket at lunch he wouldn’t
be able to get back in again. If you instrument something or someone to
see where it is and what it’s up to, make sure you are measuring the right
thing.
Where was I? Without duplicating myself, even with an ersatz, phony,
proxy other to do my dirty work for me, and attempting to slow down and
just single task, I still might not achieve everything I set out to do. I can
be self-reflective though. It is useful to keep notes to see how well I’m
doing, or my team is doing. For those of a geek bent, there are various ways
of automatically keeping track of things. If your code-base isn’t terabad,
then you might have it running on a continuous integration box allowing
you to perform some software archaeology [TICOSA]. You can graph the
build times, quickly spot churn in various code modules, notice early if
tests slow down or speed up, glance at a burn-down chart, or see the team
is giving 120%.2 Beyond the day-job, technology can be used to track all
kinds of things. Various apps exist for tracking your phone in case you lose
it. I personally need something which keeps track of where I put my notes,
but that might just mean I need to be better organised. The phone tracking
apps have recently moved up a notch, with ‘spy apps’ hitting the headlines
[Spy apps]. The premise appears to be that the teens spend so much of the
time on their smartphones, communicating with their friends and strangers
on various forums and the like, that parents can take an interest by tracking
exactly what they have been up to. Furthermore some of these applications
claim to allow parents to track exactly where the children are. Without
having delved into the details of the technology I suspect the apps will
potentially tell parents exactly where the smartphone in question is, which
may not be the same thing. This may require some form of tracking device
Warwick also surgically implanted a trivial chip in his arm, which
allowed sensors to detect his presence and do things like turn on lights
and open doors, then romped about in the media explaining gravely
that he was now a cyborg: ‘Being a human was OK,’ he said. ‘But being
a cyborg has a lot more to offer.’ Bravo. It was never clear why he
couldn’t just carry the chip in his pocket. [BadScience]
Has this diversion allowed me to clarify my thoughts and get myself on
track? Almost certainly not. It has made me less concerned about figuring
out where I am and what time it is. There’s nothing like taking your watch
off on holiday and just walking round an unknown town to see what
happens. Getting lost can be a fruitful journey of discovery. We have all
heard various myths and legends of people heading into the desert to
mediate or find themselves. Being a bit vague is
sometimes ok. Now if only I could remember where
my smart-phone is. Let’s ring it from the landline and
see if that helps.
References
[BadScience] http://www.badscience.net/2004/04/the-return-of-captaincyborg/
[FUD] ‘FUD – Fear, uncertainty and doubt’, Frances Buontempo
Overload 125, Feb 2015
[Gibson] The Peripheral Sep 2014, Putnam.
[Gorillaz] http://en.wikipedia.org/wiki/Gorillaz
[Hyperphysics] http://hyperphysics.phy-astr.gsu.edu/hbase/relativ/
tdil.html
[Kraftwerk] http://www.imdb.com/title/tt3262308/
[LSRO] http://lsro.epfl.ch/simulators ‘Surgical simulators with haptic
feedback – training of minimally invasive surgery’
[Mills] Nigel Mills, http://www.bbc.co.uk/news/uk-politics-30375609
[SAFFiR] Shipboard Autonomous Firefighting Robot
http://www.livescience.com/49719-humanoid-robot-fightsfires.html
[Spy apps] for example http://www.bbc.co.uk/news/technology30930512
[TICOSA] http://ticosa.org/
2. I suspect we set that graph up incorrectly.
April 2015 | Overload | 3
FEATURE
SERGEY IGNATCHENKO
Non-Superfluous People:
UX Specialists
User experience specialists are sometimes
regarded as superfluous people. Sergey
Ignatchenko demonstrates why they can be vital.
Disclaimer: as usual, the opinions within this article are those of ‘No Bugs’
Bunny, and do not necessarily coincide with the opinions of the translators
and Overload editors; also, please keep in mind that translation difficulties
from Lapine (like those described in [Loganberry04]) might have prevented
an exact translation. In addition, the translator and Overload expressly
disclaim all responsibility from any action or inaction resulting from reading
this article.

Jumping through further search term occurrences can be done just
by pressing Enter, which is good too.

However (LO Problem 1), if I’m already at the last occurrence of the
search term, LibreOffice shows a dialog box, asking if I want to
continue search from the beginning (which is fine). The problem
here is that the focus is not on this dialog, so to press ‘Yes’ I need to
use the mouse. Hey folks, it is a Writer application, where most of
the work is done (surprise!) with a keyboard, and moving a hand
from keyboard to mouse for such a routine task is a waste of time. It
means that we have a bit of poor UI here (and no, it is not fatal – just
as with many other UI flaws – but when we sum every bit of time
wasted, it translates into hours of unproductive activity).

Another problem (LO Problem 2) is that to move to the occurrence
of the search term in the text from the ‘Search’ box, I need to use the
mouse again. Which is not that bad, but I’d still prefer to have the
‘Tab’ key go straight there (rather than to move to the ‘Find Next’
button, which is pretty useless for the user).

And yet another problem (LO Problem 3) is that when I’ve already
moved focus from the search box to the text window, the only
obvious way to continue my search without using the mouse is to
press Ctrl+F (to move the focus to the search box), and then to press
Enter (to move to the next occurrence). This is three key presses
(two for Ctrl+F, and one for Enter), and I’d certainly prefer to have
a single one (for example, the fairly standard F3). For those who’ll
say “Hey, there is already a hotkey XX” (which I wasn’t able to find,
but it might still exist) – my answer is that “If there is such a hotkey,
it should be shown when I’m hovering the mouse over the ‘Find
Next’ button in the search bar, so I can learn about it without
Googling it”. For those who says “Hey, you can configure all the
hotkeys you want in the Tools > Customize menu” (I wasn’t able to
find this specific function there, but once again, it might still exist)
– I will note that such an obviously necessary function should be
pre-configured by default.

However, all these problems are mere peanuts compared to the Big
One (LO Problem 4). If I gave up staying with the keyboard and
conceded to use the mouse (as a result of carefully crafted LO
Problems 1–3), then there is one more surprise, and a very nasty one.
If I click on the ‘Find Next’ button to find what I need, and the next
occurrence of the search term is within a bulleted list, then all of a
sudden, another bar (to manage the list) appears below the search
bar, moving my search bar and ‘Find Next’ button up. Therefore, if
I’m clicking ‘Find Next’ in a quick succession (and looking into the
text window), another button (which is ‘Move Up with Subpoints’)
appears right under my mouse, and I can click it without even
realizing that I’ve just changed my document!
The superfluous man (Russian: лишний человек, lishniy
chelovek) is an 1840s and 1850s Russian literary concept derived
from the Byronic hero. It refers to an individual, perhaps talented
and capable, who does not fit into social norms.
~ Wikipedia
T
his article continues a mini-series on the people who’re often seen as
‘superfluous’ either by management or by developers (and often by
both); this includes, but is not limited to, such people as testers, UX
(User eXperience) specialists, and BA (Business Analysts). However, in
practice, these people are very useful – that is, if you can find a good person
for the job (which admittedly can be difficult). The first article in the miniseries was about testers; this article tries to show why do you need to have
user interface (or more generally – User eXperience) specialists on your
team.
UI nightmares
As a user, I hate poorly designed UI. I really, really hate it. Poor UI takes
away my time (and the time of thousands and millions of other users), and
simply because of somebody not spending 5 minutes thinking about it.
Decent UI might be not rocket science, but it certainly does require a view
from the user’s perspective – one thing developers (almost universally) and
project stakeholders (sadly often) lack.
UIs designed by developers
Let’s take a look at some of the UIs designed by developers.
LibreOffice Writer ‘Find’ – strike 1
While I use LibreOffice all the time and think overall it is a decent piece
of software, the ‘Find’ feature of LibreOffice Writer is quite annoying to
say the least. This is how it works in LibreOffice 4.0 under CentOS Linux
(on other platforms details might be different):

I press Ctrl+F and it opens a ‘Search’ bar at the bottom of the screen

The focus is already in the search box, so I can start typing right
away. Good. I enter search the term, and press Enter – it finds the
first occurrence of the search term. So far so good.
‘No Bugs’ Bunny Translated from Lapine by Sergey Ignatchenko
using the classic dictionary collated by Richard Adams.
Sergey Ignatchenko has 15+ years of industry experience,
LO Problem 4 is illustrated in Figure 1 and Figure 2.
including architecture of a system which handles hundreds of millions
of user transactions per day. He is currently holding the position of
Security Researcher. Sergey can be contacted at
[email protected]
As you can see, position of the mouse on both screenshots is exactly the
same, but the button underneath has changed...
4 | Overload | April 2015
SERGEY IGNATCHENKO
FEATURE
to fix the problem somebody should have
spent time discovering that the problem
exists in the first place
This kind of things (when a potentially dangerous button appears in place
of a very harmless one) is a Big No-No in UI design (and the fact that it –
as well as all the other poor UI manifestations – happens all the time, is
not an excuse). In the case of LibreOffice, the fix for this particular problem
is trivial – to get rid of it, it is sufficient to move all ‘read-only’ bars (such
as the ‘search’ bar) below ‘modifying bars’ (such as the ‘bullet list’ bar).
However, to fix the problem somebody should have spent time discovering
that the problem exists in the first place, which apparently didn’t happen
here.
Now let’s ask ourselves the question – why did these problems occur? I
suggest that there are two reasons. The first is that it was technically
simpler to implement it this way. While LO Problem One is about
keyboard focus, which is always a headache to deal with properly, LO
Problem 2 is about overriding the default behavior of the Tab key (and
leaving it at default is always simpler), LO Problem 3 is about doing
something instead of doing nothing, and LO Problem 4 is relying on one
generic concept (that of ‘stacked bars’) without thinking about potential
interactions between those bars. On the other hand, it is certainly not rocket
science to fix these issues. OK, it might take a few hours to fix problems
1–4, but it is nothing compared to amount of work thrown into LibreOffice,
and it would improve usability by a significant margin.
The second reason is that there is nobody on the development team who
is responsible for making the software convenient for the user, and/or
having enough influence to make developers do it. Without someone who
advocates the needs of the user (against the natural need of developers to
implement the function as simply as possible), all the good intentions to
make good, usable software for the end-user won’t materialize.
As a side note: a potential argument “hey, it is free software, so you cannot
complain about it” doesn’t really fly. If you folks want your software to
Figure 1
be used, you should care about your end-user, whether the software is free
or not. Of course, software being free as in ‘free beer’ does indeed help
people to accept it, but doesn’t guarantee acceptance at any rate; crappy
free software will lose to good commercial software, whether we like it or
not.
Windows MessageBox() – strike 2
The road to hell is paved with good intentions
~ proverb
Our next example of atrocious UI design touches an (in)famous Win32
MessageBox() function. For those few who don’t know it, here is its
prototype:
int WINAPI MessageBox(HWND hwnd, LPCTSTR lpText,
LPCTSTR lpCaption, UINT uType);
If you haven’t seen it before, you’ll ask yourself – hey, how does it know
which buttons are to be shown? Apparently, buttons are ‘conveniently’
hidden behind that uType parameter, as something like
MB_YESNOCANCEL , which specifies 3 buttons – ‘Yes’, ‘No’ and
‘Cancel’– or as MB_OK with one ‘Ok’ button, or as
MB_ABORTRETRYIGNORE etc.
Now let’s see in which direction this API pushes developers. As the API
doesn’t allow you to specify exactly the buttons you need (and creating
your own message box with your own buttons, while possible, is quite a
lot of work), Windows software is full of message boxes with text like the
following:
If you want to save file before closing the window, press Yes. If you
want to discard the changes you’ve made since last save, press No.
If you want to keep editing, press Cancel.
It would be much more user-friendly to make it three buttons ‘Save File’,
‘Discard Changes’, and ‘Keep
Editing’ – and avoid the potential for
confusion and mistakes, but the
MessageBox() API encourages
developers to push complexity
towards the end-user. No wonder
developers are going down this road
(obviously paved with good
intentions by whoever designed the
MessageBox API).
But I’m not done yet with presenting
my
evidence
against
MessageBox(). The real fun starts
when your software is running on
non-English Windows. In this case,
Windows ‘conveniently’ replaces
‘Yes’, ‘No’, and ‘Cancel’ with their
translated versions (while your
software, unless you’ve spent quite
Figure 2
April 2015 | Overload | 5
FEATURE
SERGEY IGNATCHENKO
the difference between the two cases wasn’t
obvious at all to me as the user; one time it
went one route, another time it went another
way for no apparent reason
Act of God
An Act of God is a legal term for events outside human control, such as
sudden natural disasters, for which no one can be held responsible.
[Wikipedia1]
scan in this particular case, so I needed to take the pile of paper and
put it into the feeder again.

Figure 3
an effort translating it, remains in English). This often leads to such
message boxes as the one in Figure 3.
I rest my case.
Fax machine UI – strike 3, developers out
Bad UI is certainly not restricted to PCs. One of the most ridiculous UIs
I’ve seen was on a fax machine. If you ask yourself – what can be so bad
about the UI of a fax machine – I will name just a few (mis)features of the
machine. It was so bad that I don’t want to name the company that made
it, because the same company produces very usable printers, which I like
a lot; I hope that they will learn from their mistakes. So, here goes the list
of (mis)features:
When the fax I was sending didn’t go through, two things could have
happened (and the difference between the two cases wasn’t obvious at all
to me as the user; one time it went one route, another time it went another
way for no apparent reason).

In the first type of failure, the fax machine produced a sound which
was enough to awake a nearby cemetery (and of course, none of the
volume controls was able to affect it), and then it just considered the
job done.
To find out if the fax was successful or not, I needed to be near the
machine. If I was away, it blinked three times with the error
message, and then went to the idle state, leaving me, when I came
back, wondering if the fax had gone through or failed. How it should
be implemented (and actually is implemented on a competing fax
machine from a different manufacturer) is that the status should
blink, at least until the user interacts with the machine.
To re-submit the fax, I needed to feed it through the machine once
again. The machine was implemented as a scanner+printer, and by
the point of failure, the fax had already been scanned. In the process
of scanning it had already passed through the machine, but the
machine in its infinite wisdom has decided to discard results of the
6 | Overload | April 2015
In the second type of failure, there was no sound, and again the
message blinked only three times. It appeared that in this second
case, the fax machine has realized that the problem is transitory, and
that it should retry the fax some minutes later. So far so good, but:

on the front panel of the machine there was no indication
whatsoever that the machine has some fax in memory

in fact, the only place where you can find out what happened
with your fax, was three levels deep into the fax machine menu,
with one of the levels aptly named ‘MEMORY SETTINGS’
(this obviously was made to make sure that there is no chance to
operate the machine without the manual).
Overall, the machine was such a nightmare, that when a lightning strike
put the machine out of its misery, I was really grateful for this Act of God.
Once again, the reason for this UI was two-fold: first, it was technically
simpler to do it like this, and second, there was nobody to represent the
end-user and to advocate her interests.
In general (and as it has been observed in these three examples), developers
are not good at designing UIs. Personally, I feel that this is because when
designing the UI, a developer is inherently in a position of a severe conflict
of interest: on the one hand, he needs to finish the job fast (and to move
on to implementing other features), and on the other hand, user interests
may require spending another few hours before moving ahead. In theory,
this conflict of interest should always be resolved in favor of the end-user
(for example, based on the logic from [NoBugs11]), but in practice, more
often than not, developers ignore the end-user at least to some extent; in
extreme cases, it results in really atrocious UIs (like our last two examples).
UIs designed by project stakeholders
Ok, developers are not good in writing UIs. But what about project
stakeholders? They should know what is good for the user, right?
Unfortunately, the answer is “not necessarily”. In many cases, it works
well (especially if stakeholders are end-users themselves), but in many
other cases, it doesn’t. And if things go wrong with stakeholder design
decisions (especially if stakeholders have had a Big Idea which overrides
everything else, including common sense), the consequences can easily be
on the much larger scale than that of developer-designed UIs.
QuickTime Player 4 – strike one
Back in 1999, with QuickTime Player 4.0 UI, Apple had a Big Idea to
mimic a physical media player on-screen. And their developers have
faithfully implemented this idea. Which, apparently, turned out to be
SERGEY IGNATCHENKO
FEATURE
I’ve worked with a few UX specialists and
was amazed by the things they’re able to do
barely usable.[AskTog99] [HallOfShame99] As ‘the interface hall of
shame’ has put it: “In an effort to achieve what some consider to be a more
New Coke
modern appearance, Apple has removed the very interface clues and
subtleties that allowed us to learn how to use GUI in the first place. Window
borders, title bars, window management controls, meaningful control labels,
state indicators, focus indicators, default control indicators, and discernible
keyboard access mechanisms are all gone.” [HallOfShame99] Worse than
New Coke was the reformulation of Coca-Cola introduced in 1985 by The
Coca-Cola Company to replace the original formula of its flagship soft
drink, Coca-Cola (also called Coke).
that, at that point Apple has just repeated the same mistakes IBM has made
with their RealThing software a few years earlier. Strike One.
20+-field forms – strike two
One thing which project stakeholders (especially in a commercial project)
are notoriously bad with is requirements for more and more information.
The Big Idea here is that you cannot possibly have too much information.
Let’s see how a ‘sign-up’ or ‘registration’ form is usually designed in a
medium-to-big company. First, business comes in and says, “We need to
know a user name and e-mail”. Then the marketing department adds, “Hey,
we also need to know address, gender, and food preferences ” (not
specifying if it is ‘gender’ and ‘food preferences’, or ‘gender preferences’
and ‘food preferences’). And last but not least, the legal department adds
a dozen required fields such as ‘legal name’, ‘domicile’ (which nobody
except them understands anyway), ‘VAT number’, and ‘I hereby certify,
under a penalty of perjury, that I am do not intend to perform terrorist acts
using any of the web sites belonging to <insert organization name here>...’.
As a result, a simple sign-up form becomes a 20+-field monster, which
literally scares the users away (in business terms, it is characterized by a
‘drop-off rate’). It is amazing how many businesses don’t realize how
much harm can be done to their business by such a form. Just one example
with A/B split testing is provided in [VWO12], and has shown that
removing 3 fields from a sign-up form increased the number of customer
registrations by 11% (!). It means that those 20+-field monster forms are
effectively killing the very same departments which fight over the right to
insert another field into sign-up form. At the very end, the approach
described above will lead to a 50+-field form, and many-fold increase in
number of people who’re dealing with the statistics derived from this form;
the only problem will be that there is no statistics, because there are no
users.
Strike Two.
Windows 8 – Strike 3, stakeholders out
Windows 8 stakeholders have had their own Big Idea behind the new
redesigned UI – to make the UI consistent between desktop and cellphone.
And Windows 8 is actually not all bad – that is, if you have a laptop with
a touchscreen. However, if you don’t have a touchscreen (and 98+%
people don’t even now, over 2 years after the Windows 8 release) – it is
an outright disaster. It is that bad that it is often compared to the ‘New
Coke’ marketing disaster back in 1985, and that was a really bad one from
a business perspective.
While the Windows 8 UI is a subject which is easy to write another five
pages about, I feel that most of the readers have already formed their own
The American public’s reaction to the change was negative and the new
cola was a major marketing failure.
opinion about it, so I won’t go into floor-mopping with Windows 8 Metro
UI once again (it has already been done on numerous occasions).
Strike Three, Stakeholders out.
What is to be done?
“What is to be done?”
~ The name of the novel by Nikolai Chernyshevsky
So, we’ve found that developers very rarely produce a good UI, and
stakeholders, while having good ideas from time to time, are prone to
certain very costly mistakes (which originally looked like The Next Big
Thing).
At this point, our natural question is, “What can be done about it?” The
answer is simple – you need to appoint somebody whose responsibility it
is to advocate the end-user point of view.
Such a person needs information on “how usable our UI is” to do their job
– and there are multiple sources for it. One such source of information can
be the QA department (and they should be encouraged to file “usability
defects”); another source of such information can be user forums (if any)
and complaints (if you don’t have them, your project is either very new,
or is in deep trouble); and yet another source are the people using the
software on a daily basis.
And as a last (but certainly not least) source of information about usability
– you can (and I’d say, if you’re targeting more than a 1000 customers,
should) have an UX specialist on the team.
UX specialists – are they any good?
As usual, when you’re faced with a suggestion to hire yet another
specialist, there is a natural question – are they any good for the project?
And as usual, it is not all black-and-white, and there are good UX
specialists, and there are not so good ones.
I’ve worked with a few UX specialists and was amazed by the things
they’re able to do. A good UX specialist goes far beyond just trying to use
software and saying, “Tsk-tsk, it is not good”. And they go far beyond
designing a usable UI based just on their own aesthetic perceptions.
Among the UX projects I’ve seen personally was a project optimizing
software for a stock exchange. To do it, they took a control group (several
traders in a real-world environment), and monitored them for several
hours. This monitoring involved not only the distance of mouse travel
(with relation to the operation being done), but also patterns of eye
movements during the process. This information allowed not only optimal
positioning of the buttons (which is related to mouse movements), but also
April 2015 | Overload | 7
FEATURE
SERGEY IGNATCHENKO
Funnel analysis
empower such a person to open bugs (‘usability defects’), to assign
reasonably high priority to these bugs, and to ensure they are fixed.
Funnel analysis involves using a series of events that lead towards a
defined goal-from user engagement in a mobile app to a sale in an
eCommerce platform. [Wikipedia2]
If you can afford a dedicated UX specialist, and can find a good one – they
can make a Really Big Difference for your software (and to your bottom
line too). 
optimal positioning of the critical information (which is related to eye
movements). While it wasn’t immediately clear how much money this
research has made for the company, it was clear that the software is an
undisputed ‘light years ahead’ leader in terms of customer satisfaction.
Another project I’ve seen, was a much simpler one, aimed to optimize user
sign-up process. As a result of the UX review, a funnel analysis, a few
studies on a target group, some A/B split testing, and a few months of
fighting with different departments, the number of fields on the form was
reduced 3-fold, and the user drop off rate was reduced by 30% (ask your
marketing department how much this is; for those who cannot ask them,
a hint – it is HUGE).
Caveat emptor
I don’t want to say that all those who claim they’re UX specialists are good.
In fact, there are many examples of their failures too. One thing to ask
yourselves when hiring an UX specialist company is the following: do they
perform any analysis of the target audience (with trials, split testing, etc.),
or do they just have their own design ideas (without any objective
justification for them)? Do they have a way to monitor user satisfaction
(via trials, or surveys, or anything else to that effect), or they just make a
design and then they’re out of the picture? When you’re dealing with the
first type of folks, chances are they’re good, but the second type can easily
lead to an epic stakeholder-scale UI disaster.
Conclusions
In any project which has UI (and has more than 1 or 2 developers), you do
need somebody to advocate end-user interests. It is very important to
8 | Overload | April 2015
Acknowledgement
Cartoon by Sergey Gordeev from Gordeev Animation Graphics, Prague.
References
[AskTog99] ‘Apple Quicktime Player 4.0 a Real Dud’, Bruce Tongazzini,
http://www.asktog.com/readerMail/1999-06ReaderMail.html
[HallOfShame99] ‘quicktime 4.0 player’, The Interface Hall Of Shame,
2011, http://hallofshame.gp.co.at/qtime.htm
[Loganberry04] David ‘Loganberry’, Frithaes! – an Introduction to
Colloquial Lapine!, http://bitsnbobstones.watershipdown.org/lapine/
overview.html
[NoBugs11] Sergey Ignatchenko, ‘The Guy We’re All Working For’,
Overload #103.
[VWO12] ‘Removing 3 form fields increases customer registrations by
11%’, vwo.com, https://vwo.com/blog/ab-testing-form-fieldsincrease-conversions/
[Wikipedia1] https://en.wikipedia.org/wiki/Act_of_God
[Wikipedia2] https://en.wikipedia.org/wiki/Funnel_analysis
BOB SCHMIDT
FEATURE
Alternatives to Singletons
and Global Variables
Global variables and Singletons are
usually considered bad. Bob Schmidt
summarises some alternatives.
R
ecently, I posted what I thought was a simple question to the ACCU
general forum:
My current project has several objects that are instantiated by main,
and then need to be available for use by other objects and nonmember, non-friend functions [NMNF] at all levels of the call tree.
They really do represent global functionality, determined at program
startup, for which there will be only one instance per executable.
Current best practices hold that global variables are bad, as are
singletons. C++ does not support aspect-oriented programming. I
don’t want to have to pass these objects around in every constructor
and non-member function call so that they will be available when
and where they are needed.
In the past I have used a global pointer to an abstract base class,
and assigned the pointer to the instantiated derived class to this
global pointer right after the object was instantiated in main. A
similar approach would be to have a class that owns the pointer to
the derived class, which can be retrieved through a static function.
Having the globals be pointers to abstract base classes makes the
classes that use the globals easy to test, because a test or mock
object can be used in place of the real derived object. (One problem
I have with Singleton and Monostate objects in this context is the
direct tie to the concrete class.)
My Google-fu has failed me in my search for alternatives. There are
plenty of people out in the blogosphere willing to say that using
globals and singletons is bad, but few offer any practical
alternatives. I’m not against bending or breaking the rules – perhaps
one of those ‘bad’ options really is the best way. Anyone have any
suggestions? Am I over thinking this?
Motivation
My current customer has a legacy system whose real-time data acquisition
components are mostly in C code. I have been advocating migrating to
C++, and over the past several years I have written two large, stand-alone
subsystems in C++. Interfaces to new field hardware provided an ideal
opportunity to start using C++ more extensively, with the long-term goal
of re-writing some, if not all, of the existing code.
The short term goals were more realistic: develop a basic framework for
processes that conforms to the system’s current overall architecture, and
reuse existing components, wrapping the C code in C++ interfaces where
required or desirable. A lot of the existing C functions will remain NMNF
functions with C linkage.
The particular case that prompted my question is the system’s existing
inter-process communications (IPC) subsystem. The details aren’t
important (and are proprietary); the important fact for this discussion is that
each process has only one interface to the IPC subsystem, and that interface
is always initialized in main. Reads from the IPC subsystem are isolated
to the main processing thread. The send functions are called from wherever
they are needed, in the main processing thread (in response to received
data), or in one or more threads that process data from the field device.
I wanted to wrap the existing C code in a C++ interface. There have been
discussions about replacing the existing IPC scheme with something else
(such as WCF), and my goal was to create an interface that would allow
any IPC scheme to be used via dependency injection.
The forum discussion
It turns out the question was not so simple after all.
I should point out that I had already done a lot of research on the subject.
There are a lot of similar questions out there, and a seemingly unlimited
number of people with an opinion. The vast majority of responses to these
questions contained very similar answers, which boil down to ‘global
variables are bad, singletons are bad, don’t do that’. OK, I knew that
already. I was trying to find an idiomatic C++ alternative, one that didn’t
require that I pass one or more parameters to every constructor and NMNF
function just because it might be needed by the next object constructed or
the next NMNF function called.
The first several answers to my question seemed reasonable enough. They
can be summarized as, yes, global variables and singletons are bad when
abused, but there are some times and places when they solve a problem,
and can be used in very specific and limited circumstances. (I’ll call these
people the pragmatists.) One respondent mentioned the SERVICE LOCATOR
pattern, with which I was not familiar [Fowler]. It doesn’t really solve my
problem, but it is another tool in the kit.
It wasn’t too long before the strict ‘never use’ opinion showed up, and was
bolstered by several concurring opinions. (I’ll call these people the
purists.) Then the pragmatists returned, and a spirited debate was held. I
was content to read the points and counter-points as they arrived; I had
asked the question in order to be educated on the subject, and figured the
best way to learn was to keep my eyes open and my mouth closed. As with
most of these things, responses trailed off, and I was left with the email
trail.
Points and counter-points
I’m not going to spend a lot of ink trying to summarize the points made
by the two sides in this debate. The good people that participated in the
debate made their cases, and I doubt I can do them justice in a short
summary. If you are interested in all of the details you can read the entire
thread online [ACCU].
What follows is a summary of the arguments presented in the thread, along
with some commentary of my own. Fair warning – for the most part, I find
myself in the pragmatic camp.
Bob Schmidt is president of Sandia Control Systems, Inc. in
Albuquerque, New Mexico. In the software business for 33 years,
he specializes in software for the process control and access
control industries, and dabbles in the hardware side of the business
whenever he has the chance. He can be contacted at
[email protected].
April 2015 | Overload | 9
FEATURE
BOB SCHMIDT
it’s still repetitive, and a source of mental
noise for those functions that don’t need the
information themselves but are simply
passing it on down the call tree
Parameterize from Above (PfA)
The PFA pattern, introduced by Kevlin Henney in ‘The PfA Papers’
[Henney07a], was the only alternative presented as an answer to my
question. Unfortunately, its implementation is the one thing I didn’t really
want to have to do – pass the object to every class and every NMNF
function that needs it, or calls something that needs it. Currently I’m
working in a code base where in some subsystems almost every routine
has the same list of multiple parameters, and have experienced the joy of
having to add a parameter to multiple function signatures in order to get a
piece of data where I needed it, because the previous maintainer didn’t
think it would be required any further down the call tree.
Context Object Pattern
A context object aggregates multiple, repeated parameters into one
structure, so there needs to be only one common PfA parameter passed
amongst functions and classes [Henney07b]. I’ve used this pattern when
refactoring code without knowing it was a named pattern (recall the
comment above about my current project); passing one parameter is
certainly easier to manage than passing many, but it’s still repetitive, and
a source of mental noise for those functions that don’t need the information
themselves but are simply passing it on down the call tree.
Defined dependencies
One reason given for using the P F A pattern is that it defines the
dependencies of a class or NMNF function. I don’t find this reason all that
compelling. Not all objects used by a class or a function can or will be
defined as a parameter. There are other ways we declare that module A
(and its classes and/or functions) is dependent on something from module
B – include files and forward declarations are two that immediately come
to mind.
Testing
The SINGLETON and MONOSTATE patterns both deal with concrete objects,
not abstract classes. The purists rightly point out that this makes code that
use these patterns hard to test, because the functionality provided by the
objects cannot be mocked. Using PFA, the argument goes, allows the
concrete object to be passed from function to function as a pointer to the
abstract class, allowing for the substitution of mock objects during testing.
I agree with the goal, if not necessarily with the implementation.
Exceptions for logging
Logging is one of those cross-cutting concerns that aspect oriented
program [IEEE] was designed to address. Unfortunately, C++ does not
support the aspect oriented paradigm. Several purists said that they will
sometimes make an exception for logging objects, and use a Singleton or
a global, while others were adamant about never going down that path.
Order of initialization
Order of initialization issues can be tricky, particularly with static and
extern variables spread over multiple compilation units. This hasn’t been
10 | Overload | April 2015
a problem for me in past situations where I have used global variables or
SINGLETONs. The limited types of functionality provided by those objects
made it possible to initialize or instantiate the objects in main, before any
other code needed to be executed.
Multi-threading
SINGLETONs are problematic in multi-threaded environments when lazy
initialization is used. The possibility that the SINGLETON’s instance
method can be called for the ‘first’ time by two threads simultaneously
leads to a nasty race condition. The race condition is easily removed by
calling the instance method in main prior to spawning any of the threads
that use it. Instantiating an object in main and then passing it around using
PFA eliminates the race condition in a similar manner.
Other than that one case, I can’t see where PFA makes multi-threading any
easier or less prone to error. An object shared by multiple threads still has
to be thread-aware, regardless of the method used to get the object into the
thread.
Use of cin, cout, cerr, and clog
The use of the standard C++ I/O streams was offered up by the pragmatists
as an example of objects that represent global state and are not handled
using PFA. One respondent replied that “Code using these is untestable”
and in his classes he teaches his students to “only include <iostream>
in the .cpp module where main() is defined and only use the globals
there to pass them down the call chain. […] In all other modules only
use <istream> and <ostream> which define the API but not the
global objects (or sstream or fstream).”
Instance() method
Having to call an instance method to return a pointer or a reference to an
object, instead of just instantiating the object, is an awkward part of the
SINGLETON pattern. I don’t think this, by itself, is a sufficient reason to
reject the use of the pattern, but it does add to the negative pile.
Introducing the Monostate NVI Proto-Pattern
Listings 1 through 5 contain my initial solution to the problem. In my one
additional contribution to the forum thread I called it (with tongue firmly
in cheek) “… a cross between the Monostate pattern and the template
method pattern and/or Herb Sutter’s Non-Virtual Interface Idiom, with
a little pimpl added for good measure.” [Sutter01] The version presented
here is refined from that initial attempt, and (hopefully) fixes the typos.
Listing 1 is a simple abstract base class, and Listing 2 shows a class derived
from the base class. This is all standard stuff. The examples are extremely
simple, since complexity here wouldn’t add anything to the discussion.
Listing 3 shows the new class. Its primary characteristic is a pair of
constructors – one default, and one that takes a shared pointer to the
abstract base class. The constructor that takes the parameter is used to tie
the concrete derived object to the MONOSTATE NVI container. The default
constructor is used to gain access to the derived object. The class contains
BOB SCHMIDT
FEATURE
Interfaces are not supposed to change often.
When they do change, you have to modify all of
the derived classes to match the new interface
class abstract_base
{
public:
abstract_base ()
{
}
virtual ~ abstract_base ()
{
}
virtual void foo () = 0;
};
Listing 1
inline, non-virtual functions that call the virtual functions defined by the
abstract base class interface. Because the non-virtual functions are inline,
the function call is removed by the compiler, with just the virtual function
call remaining.
Listing 4 illustrates how the concrete object is created and tied to the
Monostate NVI object. Listing 5 is an example of a function that uses the
combined objects. The call to nvi.foo() in listing 5 calls foo() against
the object p instantiated in main.
This new class is not a SINGLETON; it does not create the object, and does
not have an instance() method. It looks a little like a MONOSTATE; it
maintains a shared pointer to the resource being managed.
I see several advantages to this solution. First, unlike PFA, I don’t have to
worry about passing this information around. Second, like the
MONOSTATE pattern, the object is accessed through a standard constructor.
Third, the proto-pattern accesses objects through their abstract base class
interface, making it easy to mock the object for testing.
One disadvantage of this solution is having to maintain the extra class. I
don’t consider this a big disadvantage. Interfaces are not supposed to
class concrete_derived : public abstract_base
{
public:
concrete_derived ()
: abstract_base ()
{
}
~concrete_derived ()
{
}
virtual void foo () override
{
// DO SOMETHING USEFUL
}
};
Listing 2
class mono_nvi
{
public:
explicit mono_nvi
( std::shared_ptr< abstract_base > p )
{
if ( p == nullptr )
throw ( something );
if ( mp != nullptr )
throw ( something_else );
mp = p;
}
mono_nvi ()
{
if ( mp == nullptr )
throw ( something );
}
inline void foo ()
{
mp->foo ();
}
private:
static std::shared_ptr< abstract_base > mp;
};
std::shared_ptr< abstract_base > mono_nvi::mp;
Listing 3
change often. When they do change, you have to modify all of the derived
classes to match the new interface. Under normal circumstances this
requires N changes; this proto-pattern bumps that up to N+1. A bigger
disadvantage is the lack of compiler support that indicates that the extra
class needs to be changed in response to a change in the interface.
Presumably, if the interface is changing, some code somewhere is going
int main ( int argc, char* argv[] )
{
std::shared_ptr< abstract_base > p
( new concrete_derived );
mono_nvi nvi ( p );
top_layer_function ();
}
Listing 4
void nested_function ( void )
{
mono_nvi nvi;
nvi.foo ();
}
Listing 5
April 2015 | Overload | 11
FEATURE
BOB SCHMIDT
template< class T >
class mono_nvi_template
{
public:
explicit mono_nvi_template
( std::shared_ptr< T > p )
{
// SAME AS IN LISTING 3.
}
// DEFAULT CONSTRUCTOR AND FUNCTIONS DEFINED
// THE SAME AS IN LISTING 3.
private:
static std::shared_ptr< T > mp;
};
template< class T > std::shared_ptr< T >
mono_nvi_template< T >::mp;
Listing 6
to call the new or modified function, prompting a change or addition to
the extra class.
But what about extensibility?
At one point during the project that prompted this whole discussion, a new
requirement was discussed: the program would use one derived class
object to communicate with X, and another, different derived class object
to communicate with Y. Coincidentally, during this article’s early review
process one of the reviewers wrote: “One question it might be worth
adding in, if Bob hasn’t already got it listed, is whether the design allows
for future change; for example you start with a requirement for one ‘X’
and then later on you need two of them...” It was if someone was reading
my mind. Spooky.
That requirement didn’t survive, but the question of how this might be
accomplished remained. My first thought was to use templates, which
presents a problem of its own. I’m not a strong template programmer. Most
of what I do doesn’t require that level of generality, so the templates I have
created tend to be very straightforward. So, full disclosure – it is likely that
the templates presented here are not idiomatically fully formed. (There are
no associated traits classes, for example.)
My first attempt at a template solution is shown in Listing 6. This version
allows multiple instances of proto-pattern objects to exist, as long as the
types used in the template specialization are different. That is one
weakness – the types need to be different.
template< int T >
class mono_nvi_template
{
public:
explicit mono_nvi_template
( std::shared_ptr< abstract_base > p )
{
// SAME AS IN LISTING 3.
}
// DEFAULT CONSTRUCTOR AND FUNCTIONS DEFINED
// THE SAME AS IN LISTING 3.
private:
static std::shared_ptr< abstract_base > mp;
};
template< int T > std::shared_ptr< abstract_base >
mono_nvi_template< T >::mp;
typedef
typedef
typedef
mono_nvi_template < 1 >
mono_nvi_template < 2 >
mono_nvi_template < 3 >
Listing 7
12 | Overload | April 2015
mono_nvi_one;
mono_nvi_two;
mono_nvi_three;
int main ( int argc, char* argv[] )
{
std::shared_ptr< abstract_base > p1
( new concrete_derived_1 );
std::shared_ptr< abstract_base > p2
( new concrete_derived_2 );
std::shared_ptr< abstract_base > p3
( new concrete_derived_2 );
// NOTE
// THE
// TYPES
mono_nvi_one
mnvi1 ( p1 ); // THESE ALL REFER
mono_nvi_two
mnvi2 ( p2 ); // TO DIFFERENT
mono_nvi_three mnvi3 ( p3 ); // OBJECTS OF TWO
// DIFFERENT TYPES
top_layer_function ();
}
Listing 8
void nested_function ( void )
{
mono_nvi_one mnvi1; // REFERS TO p1 IN LISTING 8
mono_nvi_two mnvi2; // REFERS TO p2 IN LISTING 8
mono_nvi_three mnvi3; // REFERS TO p3
// IN LISTING 8
// ETC.
}
Listing 9
This led to the code in Listing 7. I had no idea if this was idiomatic or not,
but it worked. It looks ugly, but I find most template code to be at least
mildly unattractive. The typedefs at the end of Listing 7 make the usage
of the template easier. (In real life I would have used enumerations instead
of the magic numbers.) Listing 8 illustrates how we can now create
multiple objects of the same or differing types. Listing 9 shows how the
new objects are used.
At this point the article was submitted for another round of reviews. The
reviewers pointed out that the way I was using the integer to specialize the
template was not, in fact, idiomatic. I was pointed in the direction of tag
dispatching, the use of empty structs whose purpose is to provide a typesafe name as a template parameter. The reviewers also recommended using
std::make_shared to create the object and a shared pointer to it in
one step [Meyers].
Listing 10 shows the class template modified to use tag dispatching. It
features two template parameters. The first typically will be the abstract
base class. The second, when the default is not used, is the tag that allows
two objects of the same type T. Listing 11 contains examples of creating
three distinct objects, similar to those created in listing 8.
template< class T, class TAG = void >
class mono_nvi_template
{
public:
explicit mono_nvi_template
( std::shared_ptr< T > p )
{
// SAME AS IN LISTING 3.
}
// DEFAULT CONSTRUCTOR AND FUNCTIONS
// DEFINED THE SAME AS IN LISTING 3.
private:
static std::shared_ptr< T > mp;
};
template< class T, class TAG >
std::shared_ptr< T > mono_nvi_template
< T, TAG >::mp;
Listing 10
BOB SCHMIDT
struct mono_nvi_two {};
// THESE ARE THE TAGS
struct mono_nvi_three {};
mono_nvi_template < abstract_base > mnvi1
( std::make_shared< concrete_derived_1 > () );
mono_nvi_template
< abstract_base, mono_nvi_two > mnvi2
( std::make_shared< concrete_derived_2 > () );
mono_nvi_template
< abstract_base, mono_nvi_three > mnvi3
( std::make_shared< concrete_derived_2 > () );
Listing 11
Wrap-up
My original solution was satisfactory; it provided the ease-of-use and
testability I was looking for. (This is the format of the solution used in the
first iteration of my client’s production code.) The final template version,
prompted by an abandoned requirement and an astute reviewer (thank
you), with further refinements provided by several reviewers, provides a
more flexible solution. 
stated in her article last month, “(the reviewers) might be able to give a
few pointers […] or other ways of doing things. ” [Buontempo15] I
certainly learned several new ways of doing things, and for that I am
grateful.
Thanks also to Michael Chiew and Larry Jankiewicz, who provided
feedback during this idea’s early development.
References
[ACCU] accu-general Mailing List, http://lists.accu.org/mailman/
private/accu-general/2015-January/046003.html
[Buontempo15] Buontempo, Frances, ‘How to Write an Article’,
Overload 125, February 2015
[Fowler] Fowler, Martin, ‘Inversion of Control Containers and the
Dependency Injection Pattern’, http://martinfowler.com/articles/
injection.html#UsingAServiceLocator
[Henney07a] Henney, Kevlin, ‘The PfA Papers: From the Top’,
Overload 80, August 2007
[Henney07b] Henney, Kevlin, ‘The PfA Papers: Context Matters’,
Overload 82, December 2007
[IEEE] Various authors, IEEE Software, January/February 2006, vol. 23
[Meyers] Meyers, Scott, Effective Modern C++, O’Reilly, Item 21,
p. 139
Acknowledgements
I would like to thank all of you who participated in the thread. In the order
in which you made your first comments, you are: Fernando Cacciola,
Anna-Jayne Metcalfe, Alison Lloyd, Balog Pal, Pete Barber, Daire
Stockdale, Aaron Ridout, Jonathan Wakely, Russel Winder, Thomas
Hawtin, Giovanni Asproni, Martin Moene, Andrew Sutton, Kris, Paul
Smith, Peter Sommerlad, and Hubert Mathews. Collectively you deserve
credit for anything I got right this month. Any mistakes I made are my own.
As always, thanks also to Fran and the reviewers. This is my first attempt
at writing about a technical subject, with real code that needed to compile
correctly, and their encouragement and input were invaluable. As Fran
An opposing opinion
One reviewer pointed out that this solution is still a global in disguise, with
the usual downsides (I agree). He or she asked the rhetorical question,
is it that much better than a simple global with get / set to do the
checking?
[Sutter01] Sutter, Herb, ‘Virtuality’, C/C++ Users Journal, 19(9),
September 2001
Corrections
There is an error in the print edition of my article in Overload 125, ‘I Like
Whitespace’. The error was discovered by Martin Moene while he was
preparing the article for the online edition. I’ll let him describe what he
found (from his email to me):
“As web editor, I already have seen Overload 125 with your article ‘I
Like Whitespace’. In it you have the [example at the bottom of the
right-hand-column on page 14] featuring a ‘dangling else’. To me
there’s a cognitive disconnect in the corrected version between
function name process_x_is_0 and value of x for which it is
invoked (!0) . I.e. the non-braced version does what it says,
whereas the second does not. (In C and C++, else is associated
with the nearest if.)”
unique_ptr< abstract_base > global_base;
void set_base
( unique_ptr< abstract_base >
{
global_base = new_base;
if ( global_base == nullptr )
throw ( something );
}
FEATURE
new_base )
abstract_base& get_base ( void )
{
if ( global_base == nullptr )
throw ( something );
return *global_base;
}
Martin is, of course, correct. My example was in error. The name of the
function called in the dangling else should have been
process_x_is_not_0. The online version of the code has been
corrected. My thanks to Martin for discovering the error and publishing
the corrected version online, and Alison Peck for the extra work she
performed supplying the corrected version to Martin.
There also is a typo (yeah, I’m going with typo) in the complex Boolean
expression at the top of the left-hand column on page 14 – an open
parenthesis is missing before the subexpression z == 6. This was
pointed out to me by astute reader Jim Dailey, who also shared his
preferred style for messy tests:
if (
void using_function ( … )
{
get_base ().foo ();
}
)
|| (
On the plus side the reviewer noted that my solution allows for
substitutability and better controlled access than a global, and gets closer
to having a template generate a lot of the boiler-plate.
One issue I see with this approach is one that the SINGLETON has – a nonstandard way of getting the object. In this case, it’s a call to
get_base(), as opposed to the instance() static member function
common to SINGLETONs.
(
( x == 0 )
&& ( x == 1 )
( y == 3 )
&& (
( z == 5 )
|| ( z == 6 )
)
)
)
I thank Jim for pointing out my error, and sharing his style.
I regret the errors and any confusion they might have caused.
Bob
April 2015 | Overload | 13
FEATURE
PETER SOMMERLAD
Variadic and Variable Templates
C++11 and 14 offer new features for Variadic and
Variable templates. Peter Sommerlad showcases the
compile-time possibilities they offer.
C
++11 introduced Variadic Templates and constexpr that ease and
allow type-safe computations at compile time. In combination with
the C++14 mechanism of Variable Templates, which actually define
constants, there are unprecedented possibilities for compile-time
computations.
This article not only shows the mechanisms available but also
demonstrates a non-trivial example, how they can be used to compute
interesting data at compile time to be put into ROM on an embedded
device, for example.
Introduction
C++ templates have allowed compile-time meta-programming for some
time now. However, with C++03 many interesting applications require
herculean efforts to achieve results using class-template specializations
and function template overloads with variable number of template
arguments. Getting such code using variable number of template
arguments right is very tedious in the C++03 landscape and even a tiny
mistake can produce horrific compiler error messages which are hard to
trace back to the origin of the error. Any user of some of the Boost libraries
that make heavy use of template meta-programming, such as
boost::spirit or boost::mpl can sing that song. [Boost]
However, the variadic templates introduced with C++11 make things
much more comfortable at the language level. <type_traits> for meta
programming were even further improved in C++14. In addition to many
more traits, C++14 introduced template aliases for each trait with a suffix
_t that allow us to rid the template code of many uses of the typename
keyword when working with traits. Also new with C++14 come variadic
lambdas, that allow us to use auto as the type for a lambda’s parameters,
so that their type can be deduced from the calling context of the lambda.
Another recent change are the relaxed rules for type deduction, so that
lambdas and auto return type functions can be specified without a trailing
return type, even in the case of multiple return statements. It is only when
multiple returned expressions differ in their type that one needs to specify
a return type explicitly.
In addition to increased possibilities with lambdas and return type
deduction, many of the limitations on C++11 constexpr functions have
also been relaxed. In the future, you might see many uses of ‘constexpr
auto’ functions that do interesting compile-time computations. Some are
shown later.
Finally, variable templates, which are actually parameterized compiletime constants, make the concept of templates more symmetric across the
language.
Prof. Peter Sommerlad is head of IFS Institute for Software at FHO/
HSR Rapperswil where he inspired the Cevelop C++ IDE
(www.cevelop.com). Peter is co-author of the books POSA Vol.1 and
Security Patterns. His goal is to make software simpler by Decremental
Development: Refactoring software down to 10% its size with better
architecture, testability and quality and functionality.
14 | Overload | April 2015
#ifndef PRINTLN_H_
#define PRINTLN_H_
#include <ostream>
// base case overload
void println(std::ostream &out){
out <<'\n';
}
// variadic template
template <typename HEAD, typename ... T>
void println(std::ostream & out,HEAD const &h, T
const & ... tail){
out << h; // cut off head
if (sizeof...(tail)){
out <<", ";
}
println(out,tail...); // recurse on tail...
}
#endif /* PRINTLN_H_ */
Listing 1
As a library component, std::tuple extends the idea of std::pair
to arbitrary collection of values of arbitrary types and
std::integer_sequence eases the writing of code employing such
lists of values.
With so much stuff, you might ask, how does that help a ‘normal’
programmer and how should I employ these. The rest of this article will
show you some applications that are useful in day-to-day work or for
embedded code employing modern compilers.
Variadic templates with typename parameters
(C++11)
Whoever has been bitten by the lack of type-safety of printf() might
employ a variadic template solution to create a type-safe println
function. Recursion is the key to defining successful variadic template
functions and makes using classical ... varargs parameters in C++ mostly
obsolete. (See Listing 1.)
A variadic template introduces a so-called ‘template parameter pack’ by
placing three dots (ellipsis) after the typename parameter introduction.
Using the template parameter pack’s name (T ) to define a function
parameter creates a parameter pack (tail). The name of the parameter
pack (tail) can later be used within the template to denote a so-called
pack-expansion, where the three dots are placed after an expression using
the parameter pack name. The corresponding expression is then repeated
for each concrete argument. In our println example, even while the base
case is not really called, an empty tail (sizeof...(tail)==0) would
not call println(), it is necessary to make the code compile. As you
might have guessed the sizeof... operator gives the number of
elements in a parameter pack. It is also applicable on a template parameter
pack name.
PETER SOMMERLAD
FEATURE
lambdas and auto return type functions can be
specified without a trailing return type
Variable templates basics (C++14)
In C++, it has always been possible to define constants that were dependent
on template arguments using static data members of a class template. To
make the language with respect to templates more symmetric and for
constants depending on template arguments, C++14 introduced variable
templates, which can even be variadic, by the way.
The canonical example from the C++ standard [ISO/IEC] is the definition
of pi for any kind of numerical type that looks like the following:
template<typename T> constexpr T pi
= T(3.1415926535897932384626433L);
This allows pi<float> or pi<double> to be computed at compile time
and used as such without casting the value. Note that the number of digits
given as a long double value are sufficient up to the precision long double
allows on today’s platforms. You can even write
pi<complex<double>> to obtain the complex constant with pi as the
real part.
If you ever need to calculate with a full circle two_pi might also be
defined accordingly:
template<typename T> constexpr T two_pi
=pi<T>+pi<T>;
While the example of Pi might not be very impressive, take a look at the
examples given later, where whole table computations are hidden behind
the initialization of a template variable.
As a more interesting helper, we implement the conversion of degrees to
radian values at compile time, using our pi<T> constant. Because degrees,
minutes and seconds can be given as integral values, we can implement
that using a variable template as well:
template <short degrees, short minutes=0,
short seconds=0>
constexpr long double
rad{(degrees+minutes/60.0L+seconds/3600.0L)
*pi<long double>/180.0L};
static_assert(pi<long double>/2 == rad<90>,
"90 degrees are pi half"); // test it
Variadic templates with non-type parameters and
std::integer_sequence (C++11/14)
In addition to typename parameter packs, C++11 and later also allow
parameter packs of non-type template parameters. The usual restrictions
on non-type template parameters apply and all arguments of a non-type
template parameter pack have to have the same type.
C++14 introduced std::integer_sequence<typename T,T ...
elts> to represent such sequences of integers or indices with
std::index_sequence<size_t ...> as different types at compile
time. A companion factory function make_index_sequence<size_t
n>() creates an index_sequence with the numbers up to n.
The following example shows how such an index_sequence can be
used to create a std::array with n elements of type size_t is
initialized-potentially at compile time-with multiples of parameter row (1
to n times):
template <size_t...I>
constexpr auto
make_compile_time_sequence(size_t const row,
std::index_sequence<I...>){
return std::array<size_t,sizeof...(I)>{
{row*(1+I)...}};
}
constexpr auto
array_1_20=make_compile_time_sequence(1,
std::make_index_sequence<20>{});
Please excuse the complication of the additional parameter row, but you
will see later that we will use that to construct different rows of a
multiplication table. For example, make_compile_time_sequence
10,std::make_index_sequence<10>{}) will create an array with
the values 10, 20, 30,... 100. That will be the last row in a multiplication
table from 1 times 1 up to 10 times 10.
While it is quite easy to convert the parameter pack to values, using packexpansion, it is impossible to use a function parameter as a template
argument within a constexpr function. This hurdle makes some
applications a bit of a burden. However, as the rules for constexpr
functions are also relaxed, there is less need for such variadic template
machinery to ensure compile-time computation of tables.
As a-slightly unnecessary-complicated example the following code shows
how to compute a multiplication table at compile time.
template <size_t...I>
constexpr
auto make_compile_time_square
(std::index_sequence<I...> ){
return std::array<std::array<size_t,
sizeof...(I)>,sizeof...(I)>
{{make_compile_time_sequence(1+I,
std::make_index_sequence
<sizeof...(I)>{})...}};
}
The pack expansion actually will generate a row in the table for each value
the parameter pack I takes. With that, we can create a complete
multiplication table from 1*1 to 20*20 with just a single declaration in the
2-dimensional array constant multab_20 at compile time:
constexpr auto multab_20 =
make_compile_time_square(
std::make_index_sequence<20>{});
The corresponding test code will output the multiplication table from the
constant multab_20 (see Listing 2). I even implemented a version that
uses std::integer_sequence<char,char ...> to create the
multiplication table as a string constant at compile time. But the code is
not as nice as I would like it to be. There is work on the way to ease compiletime string processing in a similar way and a means (already implemented
by g++ and clang) to create a char_sequence<char ...> from a
April 2015 | Overload | 15
FEATURE
PETER SOMMERLAD
it is impossible to use a function
parameter as a template argument
within a constexpr function
void testCompileTimeArray(std::ostream &out){
using namespace std;
for_each(begin(multab_20),end(multab_20),
[&out](auto row){
out << '\n';
for_each(begin(row),end(row),[&out](auto elt){
out << setw(4) << elt;
});
});
out << '\n';
}
Listing 2
regular string literal using a user-defined literal template operator that
might be standardized for C++17.
More ‘ROMable’ data
Let us conclude with an example of a compile-time computed table of sine
values to enable a quick lookup-and-interpolation-based implementation
of a sine function for an embedded system.
// sin(x) = sum (-1)^n*(x^(2*n+1))/(2n+1)!
namespace tailor {
template<typename T>
constexpr T pi = T(3.1415926535897932384626433L);
namespace detail{
constexpr long double fak(size_t n) {
long double res = 1;
for (size_t i = 2; i <= n; ++i) {
res *= i;
}
return res;
}
constexpr long double sin_denominator
(long double x, size_t n) {
long double res{ x }; // 1 + 2n
for (size_t i = 0; i < n + n; ++i) {
// naive, could be log(n), but n<20
res *= x;
}
return res;
}
To build such a table, we first need a compile-time constexpr version of
std::sin(double). This can be implemented using a Tailor-series that
converges quickly [Wikipedia]. It can be used independently from the
table to create individual sine values at compile time. A run-time use is
not recommended, because it will definitely be inferior to std::sin(x).
The code starts first with some scaffolding to implement the tailor series
development of the sine value of x. (See Listing 3.)
With that quite slow sin() function in place we can start implementing
more. Using the tricks we learned from our multiplication table we can now
implement a compile-time lookup table for the sine values for each degree
from 0..360 as in Listing 4.
Listing 5 contains some compile-time tests of our sine table to show that
the table is really ROMable using only 5 values.
And Listing 6 is our compile-time table from 0 to 360 degrees of a circle.
What is still missing from the standard
As of C++14 many standard library functions and some types are not yet
as compile-time usage friendly. For example, std::array is a literal
type, but it can not be incrementally constructed in a constexpr function.
A replacement for the time being is cloning std::array and adding
constexpr to all member functions. The keyword constexpr was only
added to the const-member functions, because these were the only useful
positions with C++11’s restrictions and nobody recognized the usefulness
for C++14 of also having the non-const member functions declared as
constexpr.
Also, the standard library’s non-modifying algorithms and may be even
some of the modifying algorithms could be used in more elaborate
constexpr functions, if they would be declared as constexpr .
16 | Overload | April 2015
template<typename T>
constexpr T two_pi =2.0l*pi<T>;
constexpr
long double adjust_to_two_pi(long double x) {
while (x > two_pi<long double> ) {
x -= two_pi<long double>;
} // very naive... not for run-time use
while (x < -two_pi<long double> ) {
x += two_pi<long double>;
}
return x;
}
} // detail
constexpr long double sin(long double x) {
long double res = 0;
x = detail::adjust_to_two_pi(x); // ensures
// convergence
for (size_t n = 0; n <= 16; ++n) {
long double const summand
{detail::sin_denominator(x, n)
/ detail::fak(2 * n + 1)};
res += n % 2 ? -summand : summand;
}
return res;
}
}
Listing 3
PETER SOMMERLAD
FEATURE
learn how to use variadic templates, since
these are reasonable and can simplify
template code significantly
namespace tables {
template <typename T, size_t ...indices>
constexpr auto
make_sine_table_impl
(std::index_sequence<indices...>){
static_assert(sizeof...(indices)>1,
"must have 2 values to interpolate");
return std::array<T,sizeof...(indices)>{{
sin(indices*two_pi<T>
/(sizeof...(indices)-1))...
}};
}
template <size_t n, typename T=long double>
constexpr auto make_sine_table=
make_sine_table_impl<T>
(std::make_index_sequence<n>{});
Listing 4
However, interpreting C++ at compile time is slowing your compiles, and
current compilers (clang, g++) will give a strict limit to the number of
computations allowed, so to be able to detect endless recursion or endless
loops. These limits usually allow for a compile time of single file to be
within a minute or a couple of minutes and it can be easily reached. For
example, I can create my sine table for 360 degrees, but not per minute or
a quarter of a degree, because of the default compiler limits, and even then
the compile time is clearly recognizable. You don’t want to include such
a header in more than one compilation unit, otherwise we get compile times
in days rather than minutes.
So compile-time constexpr computation is a powerful tool in modern
C++ to create ROMable data and relieve small processors from the burden
of some computation at run time. But it is also a potentially expensive thing
that might slow your development, if you try too complicated things at
compile time giving people again a reason to complain how slow C++
compiles. But as of today, that won’t be only the fault of the compiler, but
of the developer pushing it to its limits. So use this powerful feature wisely.
constexpr auto testsinetab=tables::make_sine_table<5,long double>;
static_assert(testsinetab[0]==0.0, "sine 0 is 0");
static_assert(abs(testsinetab[2])<1e-10, "sine pi is 0");
static_assert(abs(testsinetab.back()) <1e-10, "sine two pi is 0");
static_assert(abs(testsinetab[1]-1.0)<1e-10, "sine pi/2 is 1");
static_assert(abs(testsinetab[3]+1.0)<1e-10, "sine pi+pi/2 is -1");
Nevertheless, learn how to use variadic templates,
since these are reasonable and can simplify
template code significantly, especially in a cases
where you’d like to use template template
parameters, but that might be a story for a future
article. 
Listing 5
constexpr auto largesinetab
=tables::make_sine_table<360+1,double>;
// limited to 1 entry per degree,
// if not giving compiler argument:
//
-fconstexpr-steps=larger
// check it:
static_assert(largesinetab.front()==0,
"sine 0 is 0");
static_assert(abs(largesinetab.back())
<1e-12,"sine 2 pi is 0");
Listing 6
However, there is some tension, since some algorithms might be more
efficiently implemented as run-time versions where the limitations of
constexpr don’t apply.
A final missing piece are string literals and compile time computation of
string values. Work has started on these things and you should expect
corresponding compiler and library support for the next standard C++17
making compile time computation still more powerful, allowing even
more ROMable data being computed in C++ at compile time.
References
[Boost] Boost Libraries, http://www.boost.org;
Boost Spirit, http://www.boost.org/doc/libs/1_57_0/libs/spirit/doc/
html/index.html;
Boost MPL, http://www.boost.org/doc/libs/1_57_0/libs/mpl/doc/
index.html;
both accessed April 5th 2015
[ISO/IEC] ISO/IEC International Standard 14882, Fourth edition 201412-15, Information technology – Programming languages – C++
[Wikipedia] Sine Tailor Series definition; Wikipedia,
http://en.wikipedia.org/wiki/Sine#Series_definition, accessed
December 1st 2014
Example source code
The example source code is available on Github: https://github.com/
PeterSommerlad/Publications/tree/master/ACCU/
variadic_variable_templates
April 2015 | Overload | 17
FEATURE
PAVEL FROLOV
Resource Management with
Explicit Template Specializations
RAII is a useful idiom. Pavel Frolov
presents a powerful extension using
explicit template specialization.
R
AII is one of the most important and useful C++ idioms. RAII
efficiently relieves the programmer of manual resource management
and is a must for writing exception-safe code. Perhaps, the most
ubiquitous usage of RAII is dynamic memory management with smart
pointers, but there are a plenty of other resources for which it can be
applied, notably in the world of low-level libraries. Examples are Windows
API handles, POSIX file descriptors, OpenGL primitives, and so on.
Applying RAII: available options
There are several choices we could make when deciding to implement an
RAII wrapper for a resource of some kind:

write a specific wrapper for that particular resource type;

use a standard library smart pointer with custom deleter
(e.g., std::unique_ptr<Handle, HandleDeleter>);

implement a generic one ourselves.
The first option, writing a specific wrapper, may seem reasonable at the
beginning, and in fact, is a good starting point. The simplest RAII wrapper
may look something like Listing 1.
However, as your code base grows in size, so does the number of resources.
Eventually you’ll notice that most of resource wrappers are quite similar,
usually the only difference between them is the clean-up routine. This
causes error-prone copy/paste-style code reuse. On the other hand, this is
a great opportunity for generalization, which leads us to the second option:
smart pointers.
The smart pointer class template is a generic solution to resource
management. Even so, it has its own drawbacks, which we will discuss
shortly. As their name suggests, smart pointers were designed mainly for
memory management and their usage with other kinds of resources is often
at least inconvenient. Let’s look at the smart pointer option in more detail.
Why smart pointers are not smart enough
class ScopedResource {
public:
ScopedResource() = default;
explicit ScopedResource(Resource resource)
: resource_{ resource } {}
ScopedResource(const ScopedResource&) = delete;
ScopedResource& operator=
(const ScopedResource&)
= delete;
~ScopedResource() { DestroyResource(resource_);
}
operator const Resource&() const {
return resource_; }
private:
Resource resource_{};
};
Listing 1
Second, we could use an obscure feature of the smart pointer deleter: if
there exists a nested type named pointer , then this type is used
by unique_ptr as a managed pointer type:
struct HandleDeleter {
using pointer = Handle;
void operator()(Handle h) { CloseHandle(h); }
};
using ScopedHandle = std::unique_ptr<Handle,
HandleDeleter>;
As you can see, neither of these solutions is as user-friendly as we want
them to be, but the main problem is another. Smart pointer forces you to
make assumptions about Handle type. But handle is meant to be an
Consider the code in Listing 2.
#include <memory>
Why is the ScopedHandle constructor expecting an argument of
type void**? Recall, that smart pointers were designed primarily for
pointer types: std::unique_ptr<int> actually manages int*.
Similarly std::unique_ptr<Handle> manages Handle* which is
an alias for void** in our example. How can we work around this? First,
we could use the std::remove_pointer metafunction:
// From low-level API.
using Handle = void*;
Handle CreateHandle() { Handle h{ nullptr };
/*...*/ return h; }
void CloseHandle(Handle h) { /* ... */ }
using ScopedHandle =
std::unique_ptr<std::remove_pointer_t<Handle>,
HandleDeleter>;
Pavel Frolov is a software developer from Moscow. His
experience includes SCADA software development for space
ground-based infrastructure, namely, Angara Space Rocket
Complex and Land Launch projects. He is currently working at
Positive Technologies on an innovative automated malware
analysis system. He can be contacted at [email protected]
18 | Overload | April 2015
struct HandleDeleter {
void operator()(Handle h) { CloseHandle(h); }
};
using ScopedHandle = std::unique_ptr<Handle,
HandleDeleter>;
int main() {
// error: expected argument of type void**
ScopedHandle h{ CreateHandle() };
}
Listing 2
PAVEL FROLOV
#include <memory>
using Handle = int;
Handle CreateHandle() {
Handle h{ -1 }; /*...*/ return h; }
void CloseHandle(Handle h) { /* ... */ }
struct HandleDeleter {
using pointer = Handle;
void operator()(Handle h) { CloseHandle(h); }
};
using ScopedHandle = std::unique_ptr<Handle,
HandleDeleter>;
int main() {
// Error: type mismatch: "int" and
// "std::nullptr_t".
ScopedHandle h{ CreateHandle() };
}
Listing 3
opaque descriptor, the actual definition of handle is an implementation
detail of which the user is not required to be aware.
There is another, more serious problem with smart pointer approach (see
Listing 3).
In practice, the code above may work without problems with some of
std::unique_ptr implementations, but in general this is not
guaranteed and definitely is not portable.
The reason for an error in this case is a violation of
the NullablePointer concept [NullablePointer] by the managed type.
In a nutshell, the model of the NullablePointer concept must be
pointer-like type, comparable to nullptr. Our Handle, defined as an
alias to int , is no such thing. As a consequence, we can’t use
unique_ptr for something like POSIX file descriptors or OpenGL
GLuint handles.
There is a workaround, though. We can define an adaptor
for Handle which fulfils the requirements of NullablePointer, but
writing a wrapper for a wrapper is way too much.
Yet another smart pointer issue is related to convenience of use. Consider
idiomatic usage of a hypothetical Bitmap resource (Listing 4).
Now compare this with the usage of std::unique_ptr for
managing Bitmap (Listing 5).
FEATURE
struct BitmapDeleter {
using pointer = Bitmap;
void operator()(Bitmap bmp) {
DestroyBitmap(bmp); } };
using ScopedBitmap = std::unique_ptr<Bitmap,
BitmapDeleter>;
...
DeviceContext ctx{};
Bitmap tmp;
CreateBitmap(&tmp);
ScopedBitmap bmp{ tmp };
DrawBitmap(ctx, bmp.get());
Listing 5
As you can see, the ScopedBitmap is more awkward to use. In particular,
it can’t be passed directly to functions designed for Bitmap.
Considering the above, let’s move to the third option: implementing an
RAII wrapper ourselves.
Implementation
The implementation presented below is using a different approach to
clean-up routine than standard library smart pointers. It takes advantage
of an ability to selectively specialize non-template members of class
template [Template Specialization]. (See Listing 6.)
#include <cassert>
#include <memory> // std::addressof
template<typename ResourceTag,
typename ResourceType>
class Resource {
public:
Resource() noexcept = default;
explicit Resource(ResourceType resource)
noexcept : resource_{ resource } {}
Resource(const Resource&) = delete;
Resource& operator=(const Resource&) = delete;
Resource(Resource&& other) noexcept
: resource_{ other.resource_ }
{ other.resource_ = {}; }
// Graphics API.
bool CreateBitmap(Bitmap* bmp) {
/*...*/
return true;
}
Resource& operator=(Resource&& other) noexcept {
assert(this != std::addressof(other));
Cleanup();
resource_ = other.resource_;
other.resource_ = {};
return *this;
}
bool DestroyBitmap(Bitmap bmp) {
/* ... */
return true;
}
~Resource() { Cleanup(); }
operator const ResourceType&() const noexcept {
return resource_;
}
bool DrawBitmap(DeviceContext ctx, Bitmap bmp) {
/* ... */
return true;
}
...
ResourceType* operator&() noexcept {
Cleanup();
return &resource_;
}
// User code.
DeviceContext ctx{};
Bitmap bmp{};
CreateBitmap(&bmp);
DrawBitmap(ctx, bmp);
Listing 4
private:
// Intentionally undefined - must be
// explicitly specialized.
void Cleanup() noexcept;
ResourceType resource_{};
};
Listing 6
April 2015 | Overload | 19
FEATURE
PAVEL FROLOV
First, some minor design points.

The class is noncopyable, but movable, thus, it provides sole
ownership semantic (just like std::unique-ptr). One can
provide
shared
ownership
counterpart
(akin
to std::shared_ptr) if needed.

Taking into account that most ResourceType arguments are
simple resource handles (like void* or int), the class methods are
defined noexcept .

Overloading operator& is a questionable (if not bad) design
decision. Nevertheless, I decided to do it in order to facilitate the
usage of the class with factory functions of the form void
CreateHandle(Handle* handle).
Now to the core. As you can see, the Cleanup method which is the
cornerstone of our RAII wrapper is left undefined. As a result, an attempt
to instantiate such a class will lead to an error. The trick is to define an
explicit specialization of Cleanup for each particular resource type. For
example:
// Here "FileId" is some OS-specific file
// descriptor Type which must be closed with
// CloseFile function.
using File = Resource<struct FileIdTag, FileId>;
template<> void File::Cleanup() noexcept {
if (resource_)
CloseFile(resource_);
}
Now we can use our class to wrap FileId objects:
{
File file{ CreateFile(file_path) };
...
} // "file" will be destroyed here
You can think of the Cleanup declaration inside Resource as a
‘compile-time pure virtual function’. Similarly, explicit specialization of
Cleanup for FileId is a concrete implementation of such a function.
What’s the deal with ResourceTag?
You may wonder, why do we need a ResourceTag template parameter
which is used nowhere? It solves two purposes.
First is type-safety. Imagine two different resource types, say Bitmap and
Texture, both of which are defined as type aliases for void*. Without
the tag parameter, the compiler simply couldn’t detect the nasty bug in
Listing 7.
With the help of the tag, however, the compiler can detect the error
(Listing 8).
The second purpose of the tag: it allows us to define Cleanup
specializations for conceptually different resources having the same C++
type. Once again, imagine that our Bitmap resource requires a
DestroyBitmap function while Texture requires DestroyTexture.
using ScopedBitmap = Resource<struct BitmapTag,
Bitmap>;
using ScopedTexture = Resource<struct TextureTag,
Texture>;
int main() {
DeviceContext ctx;
ScopedBitmap bmp;
ScopedTexture t;
DrawBitmap(ctx, t);
}
// error: type mismatch
Listing 8
Without tag parameters, ScopedBitmap and ScopedTexture would
be the same type (recall that both Bitmap and Texture are in fact void*
in our example), preventing us from defining specialized clean-up routines
for each of them.
Speaking about the tag, the following expression may seem odd-looking
to some:
using File = Resource<struct FileIdTag, FileId>;
In particular, I’m talking about the usage of struct FileIdTag as a
template argument. Let’s see the equivalent expression, the meaning of
which I bet is clear to those familiar with tag dispatching [Tag
Dispatching]:
struct FileIdTag{};
using File = Resource<FileIdTag, FileId>;
Conventional tag dispatching makes use of function overloading with the
argument of tag type being an overload selector. The tag is passed to the
overloaded function by value, hence, tag type must be a complete type. In
our case however, no function overloading is taking place. The tag is used
only as a template argument to facilitate explicit specialization. Taking
into account that C++ permits incomplete types as template arguments, we
can replace tag type definition with a declaration:
struct FileIdTag;
using File = Resource<FileIdTag, FileId>;
Now, considering that FileIdTag is needed only inside the type alias
declaration, we can move it directly into the place of usage:
using File = Resource<struct FileIdTag, FileId>;
Making an explicit specialization requirement a little
more explicit
If the user fails to provide an explicit specialization for the Cleanup
method, he/she will not be able to build the program. This is by design.
However, there are two usability issues involved:

the error is reported at link-time, while it is preferable (and possible)
to detect it much earlier, at compile-time;

the error message gives the user no clue about the actual problem
and the way solve it.
using ScopedBitmap = Resource<Bitmap>;
using ScopedTexture = Resource<Texture>;
void DrawBitmap(DeviceContext& ctx,
ScopedBitmap& bmp){
/* ... */
}
Let’s try to fix it with the help of static_assert:
int main() {
DeviceContext ctx;
ScopedBitmap bmp;
ScopedTexture t;
// Passing texture to function expecting bitmap.
// Compiles OK.
DrawBitmap(ctx, t);
}
Unfortunately, it won’t work as expected: the assertion may produce an
error even though the primary Cleanup method is never instantiated. The
reason is the following: the condition inside static_assert does not
depend in any way on our class template parameters, therefore, the
compiler can evaluate the condition even before attempting to instantiate
the template.
Listing 7
20 | Overload | April 2015
void Cleanup() noexcept {
static_assert(false,
"This function must be explicitly "
"specialized.");
}
Knowing that, the fix is simple: make the condition dependent on template
parameter(s) of the class template. We could do this by writing a compile-
PAVEL FROLOV
class Bitmap {
public:
Bitmap(int width, int height);
~Bitmap(){};
int Width() const;
int Height() const;
Colour PixelColour(int x, int y) const;
void PixelColour(int x, int y, Colour colour);
DC DeviceContext() const;
/* Other methods... */
private:
int width_{};
int height_{};
// Raw resources.
BITMAP bitmap_{};
DC device_context_{};
};
Listing 9
time member function which unconditionally produces a constant of the
value false:
static constexpr bool False() noexcept {
return false; }
void Cleanup() noexcept {
static_assert(False(),
"This function must be explicitly "
"specialized.");
}
Thin wrappers vs. full-fledged abstractions
The RAII-wrapper template presented provides a thin abstraction dealing
strictly with resource management. One may argue, why bother using such
a wrapper instead of implementing a proper high-level abstraction in the
first place? As an example, consider writing a bitmap class from scratch
(see Listing 9).
To see why such a design is a bad idea in general, let’s write a constructor
for the Bitmap class (Listing 10).
As you can see our class is actually managing two resources: the bitmap
itself and the corresponding device context (this example is inspired by the
Windows GDI, where a bitmap must be backed up by an in-memory device
context for most of the drawing operations and for the sake of
interoperability with modern graphics APIs). And here goes the problem:
if the device_context_ initialization fails, the bitmap_ will be
leaked!
FEATURE
Gotchas
A couple of gotchas to watch for when defining explicit template
specializations:

explicit specialization must be defined in the same namespace as
the primary template (in our case, the Resource class template);

an explicit specialization function definition residing in a header file
must be inline: remember, the explicit specialization is a regular
function, not a template anymore.
On the other hand, consider the equivalent code with the usage of scoped
resources (Listing 11).
This example leads us to the following guideline: do not keep more than
one unmanaged resource as a class member. Better consider applying
RAII to each of the resources, and then use them as building blocks for a
more high-level abstractions. This approach both ensures exception safety
and code reuse (you can recombine those building block as you wish in
the future without the fear of introducing resource leaks).
More examples
In Listing 12, you can see some real-world examples of useful
specializations for Windows API objects. Windows API is chosen,
because it provides many opportunities for RAII application. The
examples are self-explanatory enough; no Windows API knowledge is
required.
Comparing with unique_resource from N3949
The limitations of smart pointers as a generic resource management tool
discussed earlier have led to development of standard proposal N3949
[N3949]. N3949 suggests a unique_resource_t class template similar
to the one presented in the article but with a more conventional approach
to the clean-up routine (i.e., in the vein of std::unique_ptr) – see
Listing 13.
As you can see, unique_resource_t uses a clean-up routine per
resource instance, while the Resource class utilizes a clean-up routine
per resource type approach. Conceptually, a clean-up routine is more a
property of a resource type rather than instance (this is obvious from most
of the real-world usage of RAII wrappers). Consequently, it becomes
using ScopedBitmap = Resource<struct BitmapTag,
BITMAP>;
using ScopedDc = Resource<struct DcTag, DC>;
...
Bitmap::Bitmap(int width, int height)
: width_{ width }, height_{ height } {
// Create bitmap.
bitmap_ = ScopedBitmap{
CreateBitmap(width, height) };
if (!bitmap_)
throw std::runtime_error
{ "Failed to create bitmap." };
Bitmap::Bitmap(int width, int height)
: width_{ width }, height_{ height } {
// Create bitmap.
bitmap_ = CreateBitmap(width, height);
if (!bitmap_)
throw std::runtime_error{
"Failed to create bitmap." };
// Create device context.
device_context_ = CreateCompatibleDc();
if (!device_context_)
// bitmap_ will be leaked here!
throw std::runtime_error{
"Failed to create bitmap DC." };
// Create device context.
device_context_ = ScopedDc
{ CreateCompatibleDc() };
if (!device_context_)
// Safe: bitmap_ will be destroyed in case of
// exception.
throw std::runtime_error
{ "Failed to create bitmap DC." };
// Select bitmap into device context.
// ...
// Select bitmap into device context.
// ...
}
Listing 10
}
Listing 11
April 2015 | Overload | 21
FEATURE
PAVEL FROLOV
// Windows handle.
using Handle = Resource<struct HandleTag, HANDLE>;
template<> void Handle::Cleanup() noexcept {
if (resource_ &&
resource_ != INVALID_HANDLE_VALUE)
CloseHandle(resource_);
}
// WinInet handle.
using InetHandle
= Resource<struct InetHandleTag, HINTERNET>;
template<> void InetHandle::Cleanup() noexcept {
if (resource_)
InternetCloseHandle(resource_);
}
// WinHttp handle.
using HttpHandle
= Resource<struct HttpHandleTag, HINTERNET>;
template<> void HttpHandle::Cleanup() noexcept {
if (resource_)
WinHttpCloseHandle(resource_);
}
// Pointer to SID.
using Psid = Resource<struct PsidTag, PSID>;
template<> void Psid::Cleanup() noexcept {
if (resource_)
FreeSid(resource_);
}
// Network Management API string buffer.
using NetApiString
= Resource<struct NetApiStringTag, wchar_t*>;
template<> void NetApiString::Cleanup()
noexcept {
if (resource_ && NetApiBufferFree(resource_)
!= NERR_Success) {
// Log diagnostic message in case of error.
}
}
// Certificate store handle.
using CertStore
= Resource<struct CertStoreTag, HCERTSTORE>;
template<> void CertStore::Cleanup() noexcept {
if (resource_)
CertCloseStore(resource_,
CERT_CLOSE_STORE_FORCE_FLAG);
}
Listing 12
tedious to specify clean-up routine during each and every resource
creation. On rare occasions, however, such a flexibility can be useful. As
an example, consider the clean-up function which takes a policy flag to
control the deletion of resource, such as the CertCloseStore Windows
API function presented earlier in the examples section.
Speaking about the amount of code needed to define a resource wrapper,
there is not much difference between Resource and
unique_resource_t . Personally, I find function specialization
definition to be more elegant than functor definition (i.e., struct with
operator()). For unique_resource_t we could also use in-place
lambda instead, as shown above, but this quickly becomes inconvenient
as we need to create resources in more than one place in the code (the
lambda definition must be repeated then). On the other hand, passing
callable objects in constructors to provide custom logic is widely used in
C++, while defining explicit specializations may seem more exotic to most
programmers.
22 | Overload | April 2015
template<typename Resource, typename Deleter>
class unique_resource_t {
/* … */
};
// Factory.
template<typename Resource, typename Deleter>
unique_resource_t<Resource, Deleter>
unique_resource(Resource&& r, Deleter d) noexcept
{
/* … */
}
...
// Usage (predefined deleter).
struct ResourceDeleter {
void operator()(Resource resource)
const noexcept {
if (resource)
DestroyResource(resource);
}
};
using ScopedResource =
unique_resource_t<Resource, ResourceDeleter>;
ScopedResource r{ CreateResource(),
ResourceDeleter{} };
// Alternative usage (in-place deleter definition).
auto r2{ unique_resource(
CreateResource(),
[](Resource r){ if (r) DestroyResource(r); })
};
Listing 13
Conclusion
The RAII wrapper presented in the article resolves most of the
shortcomings of standard library smart pointers for managing resources of
types other than memory. To be specific:

non-obvious declaration syntax for pointer type aliases;

limited support for non-pointer types;

awkward usage of managed resources with low-level APIs in
comparison to unmanaged ones.
We have also become acquainted with a simple but interesting static
polymorphism technique based on the usage of explicit template
specialization. Historically, explicit template specialization has had the
fame of an advanced language feature aimed mainly towards library
implementers and experienced users. As you can see however, it can play
a much more prominent role of a core abstraction mechanism on par with
virtual functions, rather than being merely a helpful utility in a library
implementer’s toolbox. I am convinced that the full potential of this feature
has yet to be unlocked. 
Code available at https://goo.gl/cK46xF
References
[N3949] http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2014/
n3949.pdf
[NullablePointer] http://en.cppreference.com/w/cpp/concept/
NullablePointer
[Tag Dispatching] http://www.boost.org/community/
generic_programming.html#tag_dispatching
[Template Specialization] http://en.cppreference.com/w/cpp/language/
template_specialization
VLADIMIR GRIGORIEV
FEATURE
iterator_pair – A Simple and
Useful Iterator Adapter
Can you form a new contain from two
others? Vladimir Grigoriev reminds us
how to write an iterator.
T
he article describes a simple and useful iterator adapter
iterator_pair, provides its implementation and shows some use
cases of the iterator. It argues that because standard iterator adapters
hide the property value type of the underlying containers and objects, they
make it difficult to write safe and generic code. The article points to a
potention surprise with the standard algorithms std::partial_sum
and std::adjacent_difference, and offers a way to remedy it.
Readers may also be interested to know that there is an iterator named
zip_iterator in the boost libraries that is also based on the idea of
combining several iterators as one iterator. It models Readable iterator as
described in the documentation on the iterator [Boost]. Nevertheless
zip_iterator and iterator_pair are different iterator adapters,
with different implementations and their own usages.
Let’s help a student
In a forum for beginners I encountered the following assignment.
Let’s assume that there are two arrays of integers, A and B, with
equal sizes. Form third array C with the same size elements of which
will be set to the minimum of values of corresponding elements of
the first two arrays.
It is obvious that the task of a beginner is to demonstrate his skill in
managing loops.
Nevertheless the assignment can be easy done by means of the standard
algorithm std::transform . Listing 1 is a possible solution of the
assignment using std::transform.
Note: If you are using MS Visual C++ to compile the code then specify =
as the capture-default option in the lambda expression used in the calls of
the algorithm std::generate. Otherwise you can get a compilation
error.
The program might have the following output:
A: 2 0 3 7 2 4 0 4 2 2 6 5 3 6 7 0 6 9 0 2
B: 6 2 1 4 0 5 5 4 6 0 2 8 2 7 7 7 1 7 3 5
C: 2 0 1 4 0 4 0 4 2 0 2 5 2 6 7 0 1 7 0 2
This is nothing unusual or difficult. The only detail you should take into
account is that you may not write simply std::min<int> instead of the
lambda expression in the call of the algorithm because the compiler will
report an error saying that there is an ambiguity for std::min<int>.
Indeed, when the C++ 2011 Standard was adopted a new special type
appeared. It is std::initializer_list . Consequently several
standard algorithms, including std::min, were overloaded to accept
std::initializer_list as a parameter type. So std::min<int>
can be either a specialization of the function with two parameters of type
int (more precisely of type const int &) or a specialization of the
function that has parameter of type std::initializer_list<int>.
Thus you need a means of helping the compiler to select the right function.
And using lambda expressions as wrappers around overloaded functions
in similar situations is such a means. Of course you may omit the template
#include <iostream>
#include <algorithm>
#include <iterator>
#include <cstdlib>
#include <ctime>
int main()
{
const size_t N = 20;
int a[N], b[N], c[N];
std::srand( ( unsigned int )
std::time( nullptr ) );
std::generate( std::begin( a ), std::end( a ),
[] { return ( std::rand() % ( N / 2 ) ); } );
std::cout << "A: ";
for ( int x : a ) std::cout << x << ' ';
std::cout << std::endl;
std::generate( std::begin( b ), std::end( b ),
[] { return ( std::rand() % ( N / 2 ) ); } );
std::cout << "B: ";
for ( int x : b ) std::cout << x << ' ';
std::cout << std::endl;
std::transform( std::begin( a ), std::end( a ),
std::begin( b ), std::begin( c ),
[] ( int x, int y )
{
return ( std::min( x, y ) );
} );
std::cout << "C: ";
for ( int x : c ) std::cout << x << ' ';
std::cout << std::endl;
}
Listing 1
argument of the function within the lambda expression because the
compiler can deduce it itself in this case.
From the simple to the complex
Whether a student will use the standard algorithm or write an appropriate
loop himself is not important for us now: as usual, there is just a step
between trivial and non-trivial tasks.
Indeed, let’s make the assignment a bit more complicated. Assume that
now we need to fill elements of one array, array C, with the minimum
values of corresponding elements of the original arrays and to fill elements
Vladimir Grigoriev is active in user groups devoted to the C++
Standard at isocpp.org. He submitted several proposals to the C++
Standards Committee, some of which were adopted. He is a highly
visible participant of C and C++ sections at Stack Overflow. His
nickname there is Vlad from Moscow.
April 2015 | Overload | 23
FEATURE
VLADIMIR GRIGORIEV
what I am sure of is that if such solutions using
other standard algorithms exist, they will look
artificial and will not be easily readable
of another array, say, array D, with the maximum values of corresponding
elements of arrays A and B.
What should we do in this case? We could use the previous call of
std::transform twice, first to form array C with the minimum values
and then, in the second call, to form array D with the maximum values.
However, it is obvious that such an approach is inefficient. Moreover, if
we make the assignment even more complicated and require that instead
of using two additional arrays, C and D, we have to overwrite the original
arrays A and B with the minimum and maximum values of their elements
respectively – that is, to do the task ‘in place’ – it is clear that this approach
simply will not work.
that returns a single object for std::minmax) that returns a pair of objects
(actually one object of type std::pair<const int &, const int
&>)?
It is an idea! Let’s write the renewed call of std::transform first and
then discuss it.
std::transform( std::begin( a ), std::end( a ),
std::begin( b ), make_iterator_pair
( std::begin( c ),std::begin( d ) ),
[] ( int x, int y )
{
return ( std::minmax( x, y ) );
} );
Is it a dead end and will we be forced to use an ordinary loop as a student
would do?
So how does it look?
It is possible that these complicated assignments could be done with some
other standard algorithms. I think that maybe std::inner_product
will cope with the tasks. I am not sure, I did not try it. It is simply my
supposition.
The functional object returns an object of type std::pair<const int
&, const int &> and it is met by an iterator of type std::pair<int
*, int *> that is by the pair of iterators. Each iterator will get its own
value. Thus arrays C and D will be filled as required.
But what I am sure of is that if such solutions using other standard
algorithms exist, they will look artificial and will not be easily readable.
Of course there is no such a function as make_iterator_pair at
present in the C++ Standard, in the same way as there is no iterator adapter
iterator_pair itself. It is only my proposal. However, as you can see
if there were such constructions our complicated assignments could be
done very simply and elegantly.
It seems that there are no satisfactory solutions. There are indeed no
satisfactory solutions if we must act within the frames of available standard
constructions (algorithms, iterators and so on) provided by the C++
Standard (if you have such solutions please let me know).
However, let’s not abandon hope but return to the previous code example
and consider the call of std::transform more closely.
std::transform( std::begin( a ), std::end( a ),
std::begin( b ), std::begin( c ),
[] ( int x, int y )
{
return ( std::min( x, y ) );
} );
For the new, more complicated, assignments we need to get the minimum
and maximum values of each pair of elements of arrays A and B
simultaneously. There is a standard algorithm that can do this job. It is
algorithm std::minmax. Not so bad! Let’s replace std::min in the
lambda expression with std::minmax.
std::transform( std::begin( a ), std::end( a ),
std::begin( b ), std::begin( c ),
[] ( int x, int y )
{
return ( std::minmax( x, y ) );
} );
So the lambda expression will now return an object of type
std::pair<const int &, const int &>. The problem is that the
iterator for array C cannot accept objects of that type and our purpose is
to deal with two arrays simultaneously instead of one array.
Hmm...What will happen if we substitute the iterator of array C for a pair
of iterators (the same way as we did with the substitution of std::min
24 | Overload | April 2015
Now all that we need to enjoy the luxury of using this iterator adapter to
run programs for the assignments is to implement it.
Time to build the iterator adapter
The iterator adapter iterator_pair will have the iterator category
std::output_iterator_tag. This allows us to combine any two
iterators that satisfy the requirements of output iterators. Its value type will
be a pair of value types of the underlying iterators. For convenience the
definition of the iterator adapter is placed in a separate header file with
name "iterator_pair.h" inside the name space usr.
Listing 2 is the iterator adapter definition, with boilerplate include
guards removed for brevity.
All is ready. It is time to enjoy the fruits of our labor. Below a program is
presented that performs both assignments. First, it fills the two arrays C
and D with the minimum and maximum values of each pair of elements
of arrays A and B, and then overwrites arrays A and B themselves with
the same minimum and maximum values. See Listing 3.
The program might have the following output:
A:
B:
C:
D:
3
6
3
6
1
8
1
8
2
7
2
7
2
2
2
2
9
5
5
9
3
7
3
7
4
5
4
5
9
2
2
9
8
1
1
8
8
2
2
8
2
4
2
4
5
7
5
7
7
3
3
7
2
7
2
7
3
1
1
3
5
2
2
5
3
2
2
3
0
5
0
5
8
3
3
8
4
2
2
4
A:
B:
A:
B:
3
6
3
6
1
8
1
8
2
7
2
7
2
2
2
2
9
5
5
9
3
7
3
7
4
5
4
5
9
2
2
9
8
1
1
8
8
2
2
8
2
4
2
4
5
7
5
7
7
3
3
7
2
7
2
7
3
1
1
3
5
2
2
5
3
2
2
3
0
5
0
5
8
3
3
8
4
2
2
4
VLADIMIR GRIGORIEV
FEATURE
two separate operations – the default
construction of objects and assigning actual
values to them – can be substituted for one
operation of copy construction
#include <iterator>
#include <utility>
namespace usr
{
using namespace std;
template <class Iterator1, class Iterator2>
class iterator_pair
: public iterator<output_iterator_tag,
pair<typename iterator_traits<Iterator1>
::value_type,
typename iterator_traits<Iterator2>
::value_type>, void, void, void>
{
public:
typedef pair<Iterator1, Iterator2>
iterator_type;
iterator_pair( Iterator1, Iterator2 );
explicit iterator_pair( const pair<Iterator1,
Iterator2> & );
explicit iterator_pair( pair<Iterator1,
Iterator2> && );
iterator_type base() const;
iterator_pair<Iterator1, Iterator2> &
operator =( const
pair<typename iterator_traits<Iterator1>
::value_type,
typename iterator_traits<Iterator2>
::value_type> & );
iterator_pair<Iterator1, Iterator2> &
operator =
( pair<typename iterator_traits<Iterator1>
::value_type,
typename iterator_traits<Iterator2>
::value_type> && );
iterator_pair<Iterator1, Iterator2>
& operator *();
iterator_pair<Iterator1, Iterator2>
& operator ++();
iterator_pair<Iterator1, Iterator2>
operator ++( int );
protected:
iterator_type it;
};
template <class Iterator1, class Iterator2>
iterator_pair<Iterator1, Iterator2>
make_iterator_pair( Iterator1, Iterator2 );
template <class Iterator1, class Iterator2>
iterator_pair<Iterator1, Iterator2>
make_iterator_pair( const pair<Iterator1,
Iterator2> & );
}
Listing 2
namespace usr
{
template <class Iterator1, class Iterator2>
iterator_pair<Iterator1,
Iterator2>::iterator_pair
( Iterator1 it1, Iterator2 it2 )
: it( it1, it2 ) {}
template <class Iterator1, class Iterator2>
iterator_pair<Iterator1,
Iterator2>::iterator_pair
( const pair<Iterator1, Iterator2> &it_pair )
: it( it_pair ) {}
template <class Iterator1, class Iterator2>
typename iterator_pair<Iterator1,
Iterator2>::iterator_type
iterator_pair<Iterator1, Iterator2>::base() const
{
return ( it );
}
template <class Iterator1, class Iterator2>
iterator_pair<Iterator1, Iterator2> &
iterator_pair<Iterator1, Iterator2>::operator =
( const pair<typename iterator_traits<Iterator1>
::value_type,
typename iterator_traits<Iterator2>
::value_type> &value )
{
*( it.first ) = value.first;
*( it.second ) = value.second;
return ( *this );
}
template <class Iterator1, class Iterator2>
iterator_pair<Iterator1, Iterator2> &
iterator_pair<Iterator1, Iterator2>::operator =
( pair<typename
iterator_traits<Iterator1>::value_type,
typename
iterator_traits<Iterator2>::value_type> &&value )
{
*( it.first ) = value.first;
*( it.second ) = value.second;
return ( *this );
}
template <class Iterator1, class Iterator2>
iterator_pair<Iterator1, Iterator2> &
iterator_pair<Iterator1, Iterator2>::operator *()
{
return ( *this );
}
Listing 2 (cond’t)
April 2015 | Overload | 25
FEATURE
VLADIMIR GRIGORIEV
template <class Iterator1, class Iterator2>
iterator_pair<Iterator1, Iterator2> &
iterator_pair<Iterator1, Iterator2>::operator
++()
{
++it.first;
++it.second;
return ( *this );
}
template <class Iterator1, class Iterator2>
iterator_pair<Iterator1, Iterator2>
iterator_pair<Iterator1, Iterator2>
::operator ++( int )
{
iterator_pair<Iterator1, Iterator2> tmp( it );
it.first++;
it.second++;
return ( tmp );
}
template <class Iterator1, class Iterator2>
iterator_pair<Iterator1, Iterator2>
make_iterator_pair( pair<Iterator1, Iterator2>
&&it_pair )
{
return ( iterator_pair<Iterator1,
Iterator2>( it_pair ) );
}
template <class Iterator1, class Iterator2>
iterator_pair<Iterator1, Iterator2>
make_iterator_pair( Iterator1 it1, Iterator2 it2 )
{
return ( iterator_pair<Iterator1,
Iterator2>( it1, it2 ) );
}
template <class Iterator1, class Iterator2>
iterator_pair<Iterator1, Iterator2>
make_iterator_pair( const pair<Iterator1,
Iterator2> &it_pair )
{
return ( iterator_pair<Iterator1,
Iterator2>( it_pair ) );
}
}
Listing 2 (cond’t)
You can see that the program has done all that is required in the
assignments.
To gain a more complete insight about the possibilities of the iterator
adapter, let’s consider one more use case that occurs in practice where the
iterator adapter would come in handy.
Sometimes it is required to copy the key values and mapped values of some
associative container having, for example, type std::map in two other
separate sequential containers. So let’s assume that there is a container of
type std::map<int, std::string> and your task, for example, is
to copy the key values of the map in a container of type
std::vector<int> and mapped values of the map in a container of type
std::forward_list<std::string>.
Before you continue to read the article further, it would be useful for you
to try to do the assignment yourself using some standard algorithms and
then compare your solution with the solution based on applying iterator
adapter iterator_pair.
Have you written your solution yet? How much time did it take to write it?
Now compare it with what is being suggested in Listing 4.
The program has the following output:
0 1 2 3 4
Hello new iterator adapter iterator_pair!
26 | Overload | April 2015
#include "iterator_pair.h"
int main()
{
const size_t N = 20;
int a[N], b[N], c[N], d[N];
std::srand
( ( unsigned int )std::time( nullptr ) );
std::generate( std::begin( a ), std::end( a ),
[] { return ( std::rand() % ( N / 2 ) ); } );
std::cout << "A: ";
for ( int x : a ) std::cout << x << ' ';
std::cout << std::endl;
std::generate( std::begin( b ), std::end( b ),
[] { return ( std::rand() % ( N / 2 ) ); } );
std::cout << "B: ";
for ( int x : b ) std::cout << x << ' ';
std::cout << std::endl;
std::transform( std::begin( a ), std::end( a ),
std::begin( b ),
usr::make_iterator_pair( std::begin( c ),
std::begin( d ) ), [] ( int x, int y )
{
return ( std::minmax( x, y ) );
} );
std::cout << "C: ";
for ( int x : c ) std::cout << x << ' ';
std::cout << std::endl;
std::cout << "D: ";
for ( int x : d ) std::cout << x << ' ';
std::cout << std::endl;
std::cout << std::endl;
std::cout << "A: ";
for ( int x : a ) std::cout << x << ' ';
std::cout << std::endl;
std::cout << "B: ";
for ( int x : b ) std::cout << x << ' ';
std::cout << std::endl;
std::transform( std::begin( a ), std::end( a ),
std::begin( b ),
usr::make_iterator_pair( std::begin( a ),
std::begin( b ) ), [] ( int x, int y )
{
return ( std::minmax( x, y ) );
} );
std::cout << "A: ";
for ( int x : a ) std::cout << x << ' ';
std::cout << std::endl;
std::cout << "B: ";
for ( int x : b ) std::cout << x << ' ';
std::cout << std::endl;
}
Listing 3
The central point of the program is the statement
std::copy( m.begin(), m.end(),
usr::make_iterator_pair( v.begin(), l.begin() ) );
that does all the work. I think that you will agree with me that the statement
looks very clear and does not require much time to understand what is
being done here.
It seems that we could end the article here. We have gotten a remarkably
simple and useful iterator adapter. However, it is the C++ Standard that
does not allow us to do this.
In the previous listings, the given number of elements of containers
std::vector<int> and std::forward_list<std::string>
were created beforehand. So at first the elements were created and
initialized with the default values and only then the actual values were
assigned to them in the call of algorithm std::copy.
VLADIMIR GRIGORIEV
#include "iterator_pair.h"
int main()
{
std::map<int, std::string> m;
std::istringstream is
( "Hello new iterator adapter
iterator_pair!" );
int i = 0;
std::transform(
std::istream_iterator<std::string>( is ),
std::istream_iterator<std::string>(),
std::inserter( m, m.begin() ),
[&i]( const std::string &s )
{
return ( std::make_pair( i++, s ) );
} );
std::vector<int> v( m.size() );
std::forward_list<std::string> l( m.size() );
std::copy( m.begin(), m.end(),
usr::make_iterator_pair( v.begin(),
l.begin() ) );
for ( int x : v ) std::cout << x << ' ';
std::cout << std::endl;
for ( const std::string &s : l )
std::cout << s << ' ';
std::cout << std::endl;
}
Listing 4
FEATURE
#include "iterator_pair.h"
int main()
{
std::map<int, std::string> m;
std::istringstream is
( "Hello new iterator adapter
iterator_pair!" );
int i = 0;
std::transform
( std::istream_iterator<std::string>( is ),
std::istream_iterator<std::string>(),
std::inserter( m, m.begin() ),
[&i]( const std::string &s )
{
return ( std::make_pair( i++, s ) );
} );
std::vector<int> v;
v.reserve( m.size() );
std::forward_list<std::string> l;
std::copy( m.begin(), m.end(),
usr::make_iterator_pair
( std::back_inserter( v ),
std::front_inserter( l ) ) );
for ( int x : v ) std::cout << x << ' ';
std::cout << std::endl;
for ( const std::string &s : l )
std::cout << s << ' ';
std::cout << std::endl;
}
Listing 5
The two separate operations – the default construction of objects and
assigning actual values to them – can be substituted for one operation of
copy construction. Calls of the copy assignment operator can be
eliminated. For simple types – such as fundamental types – it is not as
important. However, in general for objects of complex types, two calls of
two special functions instead of one call of one special function can be
wasteful.
Moreover, if we want new elements to be added to container
std::forward_list<std::string> in the reverse order relative to
the order of the elements in container std::map<int, std::string>
then it makes no sense to create the elements of
std::forward_list<std::string> beforehand, because the class
std::forward_list does not have a reverse iterator.
Therefore let’s make some minor changes to the program. We will not
create elements of containers std::vector<int> and
std::forward_list<std::string> beforehand. Instead only
reserve enough memory for the container std::vector<int>’s future
elements and then respectively std::back_insert_iterator and
std::front_insert_iterator will be used in the call of
std::copy.
Now the program will look like Listing 5.
If you have typed the program correctly without any typos (or if I did this
myself correctly because you are going simply to copy and paste the
program) then you may bravely compile the program and ... you will get
compilation errors!
There is no visible cause why the code might not be compiled. Therefore
all questions should be addressed to the compiler or, to be more correct,
to the C++ Standard: why it does not allow the compiler to compile the
program.
What is your name?
If you are going to contact someone you should use either their real name
or a common form of address. Otherwise the result can be unexpected: you
might get ignored entirely or there might be even more unpleasant
consequences. (Imagine what might happen if you call your spouse by the
wrong name.)
The same is true for the world of classes and objects.
If you want your programs to be safe, flexible, and portable, you should
use the following general convention:

Your classes have to provide common forms of address for their
properties.

Code that uses your classes has to use these common forms of
address when it tries to access properties of your classes (or use their
real names, but that can be tricky).

In any case, it is better to use a common form of address because the
real name of a property can vary between implementations.
As you already know, ‘names’ in the given context means the type names
of class properties.
Here are two simple examples that demonstrate what can occur if you do
not comply with the convention.
The first example. Let’s assume that you have a project where there is a
set of flags. You chose to use the standard class std::vector<bool>
as the container for the flags. Throughout the project a few methods do
some processing based on the number of a flag in the set and its value
passed together to the methods as arguments. Of course you tried to make
your code flexible and independent of the details of the underlying
container. The code could look something like Listing 6.
After a time, you conclude that it would be better to replace
std::vector<bool> with std::bitset because the set of flags has
a small fixed size. You might think that it will be enough to substitute only
the alias declaration (and it would be indeed great if it was enough)
because, after all you tried to write the code in such a way that it would be
independent of the details of the underlying container.
However, if you make the substitution and instead of
using special_flags_t = std::vector<bool>;
write
using special_flags_t = std::bitset<N>;
(where N is some predefined constant), the project will not compile and
the compiler will issue numerous errors!
April 2015 | Overload | 27
FEATURE
VLADIMIR GRIGORIEV
using special_flags_t = std::vector<bool>;
void method1( special_flags_t::size_type
flag_number, bool flag_value )
{
// some processing using the flag
}
//...
void methodn( special_flags_t::size_type
flag_number, bool flag_value )
{
// some processing using the flag
}
//...
special_flags_t flag_values;
//...
for ( special_flags_t::size_type flag_number = 0;
flag_number < flag_values.size();
flag_number++ )
{
method1( flag_number,
flag_values[flag_number] );
}
//...
for ( special_flags_t::size_type flag_number = 0;
flag_number < flag_values.size();
flag_number++ )
{
methodn( flag_number, flag_values[flag_number]
);
}
Listing 6
The problem is that the standard class std::bitset does not provide the
common form of address size_type for its property size. Thus your good
intentions were completely subverted.
Note: the author has submitted a proposal to add a typedef declaration
size_type for standard class std::bitset.
The second example. A programmer wrote the following snippet of code
being sure that nothing extraordinary can occur within it.
std::string s;
std::string source;
std::string dest;
//...
unsigned int pos = s.find( source );
if ( pos != std::string::npos )
{
s.replace( pos, source.size(), dest );
}
std::string::size_type in the declaration of variable pos instead
of the type unsigned int.
std::string::size_type pos = s.find( source );
Or it would be even better to write simply
auto pos = s.find( source );
When you deal with containers or sequences of data directly or through
iterators, one of the most important and useful pieces of information is
about the value type of elements of the container or sequence. Without
having such information, it is difficult to write generic and safe code. You
should provide the common form of address value_type so that code
can access the elements. Otherwise you will be helpless and will be unable
to write generic template code.
That’s exactly what happened for our iterator_pair. Both of the
iterator adapters (std::back_insert_iterator and
std::front_insert_iterator ) hide the actual value of the
common form of address value_type of the underlaying containers
from the user, making the property value type itself inaccessible.
If you look at how the iterators are defined [ISO/IEC] you will see that the
second template argument of the inherited base class std::iterator
that corresponds to the common form of address value_type is set to
void. (See Listing 7.)
Thus when the property value type of iterator adapter iterator_pair
that in turn is defined like
pair
<typename iterator_traits<Iterator1>::value_type,
typename iterator_traits<Iterator2>::value_type>
was instantiated then the compiler issued an error because it cannot
instantiate std::pair with data members of type void.
These two iterators look like black holes. If a container finds itself in a
constructor of the iterators then it instantly loses without a trace its main
property, the value type.
On the other hand, if you look at how assignment operators are defined
[ISO/IEC] for these iterators, you will see that they use the property value
type of underlaying containers. For example
front_insert_iterator<Container>&
operator=(const typename
Container::value_type& value);
But they use the property bypassing their own common form of address
value_type.
The same problem exists with std::ostream_iterator. Ask any
programmer, for example, what type of objects the iterator
std::ostream_iterator<std::string>, can output and he will
answer without delay: “Objects of type std::string or at least those
objects that can be implicitly converted to type std::string.”
He was very suprised when this code snippet generated an exception
std::out_of_range!
The reason for the exception is that the size of the unsigned integral type
used by the container to represent its own property size happened to be
greater than the size of type unsigned int in the environment where
the program was compiled and run. So when string source had not been
found in string s in statement
unsigned int pos = s.find( source );
the value returned by the method find of std::string was reduced using
the arithmetic modulo 2 operation to fit pos. And then in the statement
if ( pos != std::string::npos )
it was again enlarged to the size of the type of std::string::npos
according to the rules of the usual arithmetic conversions by setting the
most significant bits to zeroes. As a result the condition in the if statement
was evaluated to true and the incorrect value of pos was used further in
method replace.
The exception could be avoided and the program would be portable if the
programmer were to use the common form of address
28 | Overload | April 2015
template <class Container>
class back_insert_iterator :
public
iterator<output_iterator_tag,void,void,
void,void>
{
//...
};
template <class Container>
class front_insert_iterator :
public
iterator<output_iterator_tag,void,void,
void,void>
{
//...
};
Listing 7
VLADIMIR GRIGORIEV
And he will be right. But if you look at how the iterator is defined [ISO/
IEC] you will see that its property value type is defined the same way as
this property is defined for iterators back_insert_iterator and
front_insert_iterator; that is, it is set to void and thus the real
value type is hidden and inaccessible for the user of the iterator.
template <class T, class charT = char,
class traits = char_traits<charT> >
class ostream_iterator:
public iterator<output_iterator_tag, void,
void, void, void>
{
//...
};
The very notion of an iterator adapter implies that it does not modify the
properties of the underlying containers or objects. Instead it gives them
new opportunities based on their own functionality.
It will not be difficult to define these iterator adapters, appending the
iterator std::insert_iterator to them in such a way that they do not
hide the main property, the value type, of the underlaying containers or
objects. Their definitions could look like Listing 8.
And it should be done because as you will soon see, the problem is not
limited only to the definition of the iterator_pair.
May an unsafe algorithm be called an algorithm in programming?
At the very beginning of the article, we helped a student. Now let the
student help us.
We will ask the student to write a function that will store partial sums of
elements of an array of type std::uint8_t[N] filled with random
values in some other integer array.
Because the student does not know standard algorithms yet, he has written
the function in C-style.
Listing 9 is his function.
template <class Container>
class back_insert_iterator :
public iterator<output_iterator_tag,
typename Container::value_type,void,void,void>
{
//...
};
template <class Container>
class front_insert_iterator :
public iterator<output_iterator_tag,
typename Container::value_type,void,void,void>
{
//...
};
template <class Container>
class insert_iterator :
public iterator<output_iterator_tag,
typename Container::value_type,void,void,void>
{
//...
};
template <class T, class charT = char,
class traits = char_traits<charT> >
class ostream_iterator:
public iterator<output_iterator_tag, T, void,
void, void>
{
//...
};
Listing 8
FEATURE
int * partial_sum( const std::uint8_t a[],
size_t n, int b[] )
{
if ( n )
{
auto acc = int( *a++ );
*b++ = acc;
while ( --n )
{
acc = acc + *a++;
*b++ = acc;
}
}
return b;
}
Listing 9
To be sure that the student’s function is correct we need to test it. Because
each of us is a qualified programmer (aren’t you?) and, in contrast to the
student, we know that the standard algorithm std::partial_sum
already exists and how to use it, we can conclude that it will be reasonable
simply to compare the results of using the student’s function and standard
algorithm std::partial_sum applied to the same array. Otherwise
what is the use of the algorithm?
The test program can look like Listing 10.
int * partial_sum( const std::uint8_t a[],
size_t n, int b[] )
{
if ( n )
{
auto acc = int( *a++ );
*b++ = acc;
while ( --n )
{
acc = acc + *a++;
*b++ = acc;
}
}
return b;
}
int main()
{
const size_t N = 10;
std::uint8_t a[N];
int b[N];
std::srand( ( unsigned int )
std::time( nullptr ) );
std::generate( std::begin( a ), std::end( a ),
[] ()
{
return std::rand() %
std::numeric_limits<std::uint8_t>::max();
} );
for ( int x : a ) std::cout << std::setw( 4 )
<< x << ' ';
std::cout << std::endl << std::endl;
::partial_sum( a, N, b );
for ( int x : b ) std::cout << std::setw( 4 )
<< x << ' ';
std::cout << std::endl;
std::partial_sum( std::begin( a ),
std::end( a ), std::begin( b ) );
for ( int x : b ) std::cout << std::setw( 4 )
<< x << ' ';
std::cout << std::endl;
}
Listing 10
April 2015 | Overload | 29
FEATURE
VLADIMIR GRIGORIEV
Well, let’s run the test program, shall we?
The program output might look like:
110
152
109
192
160
180
110
110
262
6
371
115
563
51
723
211
903
135
82
212
74
6
985 1197 1271 1277
217 173 247 253
Oops! What are we seeing? Even for the second partial sum the values do
not match and it seems that it is not the student’s function that has not
passed the test but the standard algorithm.
There is no need to go far to find the reason for the incorrect result yielded
by the algorithm. The answer is staring you in the face.
It is evident that if you are going to use some accumulator for a sequence
of data then the accumulator should be defined with a type that has a larger
size than the size of the type of the source data so that it would be able to
accomodate all accumulated values correctly without overflowing.
This is exactly how an accumulator is defined in the student’s function. It
has the type of the elements of the output array that stores accumulated
values.
On the other hand if you have a dip into the description of algorithm
std::partial_sum in the C++ Standard [ISO/IEC] you will see that
according to the C++ Standard the algorithm creates an accumulator acc
whose type is the value type of the input iterator.
Thus as the output of the test program has shown, in general you can ensure
the safe and correct work of the algorithm only for sequences that contain
a single element. You cannot control the type of the accumulator.
The same problem exists for another standard algorithm
std::adjacent_difference.
Ask yourself what is the use of such algorithms?
Fixing this defect of the algorithms will not require a lot of effort. It is
enough within the algorithms to define an accumulator as having type of
the value type of the output iterator. Below is an updated version of the
algorithm std::partial_sum without the template parameter of
operation.
template <class InputIterator,
class OutputIterator>
OutputIterator partial_sum( InputIterator first,
InputIterator last, OutputIterator result )
{
if ( first != last )
{
typename std::iterator_traits<OutputIterator>
::value_type acc = *first++;
*result++ = acc;
for ( ; first != last; ++first, ++result )
{
acc = acc + *first;
*result = acc;
}
}
return result;
}
In the same way, algorithm std::partial_sum could be defined with
the template parameter of operation and the corresponding versions of
the algorithm std::adjacent_difference.
Now if we substitute the call of standard algorithm std::partial_sum
for a call of its new implementation as it is shown in Listing 11, then both
outputs of partial sums will match each other.
140
138
70
20
134
191
181
45
140
140
278
278
348
348
368
368
502
502
693
693
874
874
919
919
56
37
975 1012
975 1012
However, this is only half the story. To get the fully functional algorithms,
the standard iterator adapters std::back_insert_iterator ,
std::front_insert_iterator, std::insert_iterator, and
30 | Overload | April 2015
int * partial_sum( const std::uint8_t a[],
size_t n, int b[] )
{
if ( n )
{
auto acc = int( *a++ );
*b++ = acc;
while ( --n )
{
acc = acc + *a++;
*b++ = acc;
}
}
return b;
}
namespace usr
{
template <class InputIterator,
class OutputIterator>
OutputIterator partial_sum( InputIterator first,
InputIterator last, OutputIterator result )
{
if ( first != last )
{
typename std::iterator_traits<OutputIterator>
::value_type acc = *first++;
*result++ = acc;
for ( ; first != last; ++first, ++result )
{
acc = acc + *first;
*result = acc;
}
}
return result;
}
}
// end of namespace usr
int main()
{
const size_t N = 10;
std::uint8_t a[N];
int b[N];
std::srand(
( unsigned int )std::time( nullptr ) );
std::generate( std::begin( a ), std::end( a ),
[] ()
{
return std::rand()
% std::numeric_limits<std::uint8_t>::max();
} );
for ( int x : a ) std::cout << std::setw( 4 )
<< x << ' ';
std::cout << std::endl << std::endl;
::partial_sum( a, N, b );
for ( int x : b ) std::cout << std::setw( 4 )
<< x << ' ';
std::cout << std::endl;
usr::partial_sum( std::begin( a ), std::end( a
),
std::begin( b ) );
for ( int x : b ) std::cout << std::setw( 4 )
<< x << ' ';
std::cout << std::endl;
}
Listing 11
std::ostream_iterator should be modified in the way described in
the previous section. Only then will separate parts of the mosaic develop
into a coherent picture.
Let’s consider two algorithms std::partial_sum and
std::accumulate that supplement each other. It is natural to expect
VLADIMIR GRIGORIEV
that partial sums of elements of a container or data sequence produced by
algorithm std::partial_sum would be the partial sums calculated
inside algorithm std::accumulate for the same container or data
sequence and that the last partial sum produced by the
std::partial_sum would be equal to the final value returned by the
std::accumulate.
In other words if, for example, there is an integer array
int a[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
you expect that these two programs
int main()
{
int a[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
for ( auto last = std::begin( a );
last != std::end( a ); )
{
std::cout << std::accumulate
( std::begin ( a ), ++last, 0 ) << " ";
}
std::cout << std::endl;
}
and
int main()
{
int a[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
std::partial_sum( std::begin( a ),
std::end( a ), std::ostream_iterator<int>
( std::cout, " " ) );
std::cout << std::endl;
}
will yield the same output
0 1 3 6 10 15 21 28 36 45
And what about for example an array of pointers to string literals instead
of the array of integers? Let the array will be defined the following way
const char * s[] =
{
"Hello ", "new ", "iterator ", "adapter ",
"iterator_pair!"
};
In this case the first program can look like
int main()
{
const char * s[] =
{
"Hello ", "new ", "iterator ", "adapter ",
"iterator_pair!"
};
for ( auto last = std::begin( s );
last != std::end( s ); )
{
std::cout << std::accumulate
( std::begin( s ), ++last, std::string() )
<< std::endl;
}
}
And its output will be
Hello
Hello
Hello
Hello
Hello
new
new iterator
new iterator adapter
new iterator adapter iterator_pair!
So the ‘partial sums’ of the pointers to string literals produced by algorithm
std::partial_sum have to look the same.
FEATURE
namespace usr
{
template <class InputIterator,
class OutputIterator>
OutputIterator partial_sum( InputIterator first,
InputIterator last, OutputIterator result )
{
if ( first != last )
{
typename
std::iterator_traits<OutputIterator>
::value_type acc = *first++;
*result++ = acc;
for ( ; first != last; ++first, ++result )
{
acc = acc + *first;
*result = acc;
}
}
return result;
}
}
// end of namespace usr
int main()
{
const char * s[] =
{
"Hello ", "new ", "iterator ", "adapter ",
"iterator_pair!"
};
usr::partial_sum( std::begin( s ),
std::end( s ),
std::ostream_iterator<std::string>
( std::cout, "\n" ) );
}
Listing 12
All you need to do to get this result is:

Substitute the standard algorithm std::partial_sum for the
updated version presented in this section of the article.

In the definition of std::ostream_iterator, change the second
template argument of its base class std::iterator from void to T as
shown earlier. You can do this temporarily in the implementation of
the iterator in the corresponding standard header provided by the
compiler.
Thus the second program will look like Listing 12.
And if you have changed std::ostream_iterator as it is described
then you indeed will see the ‘partial sums’ of the pointers to string literals
as it is shown above. On the other hand, if you will try the program using
the original standard algorithm std::partial_sum then it will not
compile!
Thus
standard algorithms std::partial_sum and
std::adjacent_difference are not only able to guarantee a correct
and predictable result, but sometimes they might not even compile. 
Acknowledgement
The author would like to thank Jonathan Leffler for his help.
References
[Boost] http://www.boost.org/doc/libs/1_57_0/libs/iterator/doc/
zip_iterator.html
[ISO/IEC] ISO/IEC 14882:2011 Programming Language C++
The full code is available at: http://cpp.forum24.ru/?1-10-0-00000000000-0-0-1428232189
April 2015 | Overload | 31
FEATURE
TEEDY DEIGH
Seeing the Wood for the Trees
The outdoors is fabled to be great. Teedy Deigh
suggests your code reflects your environment
without ever having to look out of the window.
I
t’s good to go outside and enjoy nature every now and then. Apparently.
For screen-hardened programmers this can present something of a
challenge. Outside is a domain normally negotiated in order to get to
and from the office, or for stealthy forays to the nearest supermarket to
stock up on drinks and snacks to fuel a night of hacking on some open
source or simply correcting someone in an online forum. If you want to
actually admire it, well, that’s what pictures on the web are for.
But it’s possible to have your cake and eat it without even going to the
supermarket! Look at your code. What do you see? The chances are, if you
work in a proper enterprisey system, your code will reflect your
environment: managers, proxies and singletons everywhere, with work
avoidance, vague responsibilities and unclear methods characterising how
tasks are partitioned, resources are allocated and goals are met.
Lots of bureaucracy and not a lot of action – and that’s just the identifiers.
Names and titles matter, as any interim managing senior principal vice
president of idempotent operations will tell you, but what we usually see
in enterprice code is dominated by MBA thinking and tired industrial
metaphors. It’s not just the manager and controller and factory and service
objects, but also the need, for instance, to clarify to readers that an object
that is thrown as an exception and caught as an exception is an exception
by including Exception in its name, or that a class defined as abstract
needs to be named Abstract just in case the memo didn’t get through.
Droolproof paper is in increasingly short supply.
We see the division of labour in conventions that stretch from naming into
the architecture. The traditional class struggle – where there are those who
talk about the work and those who actually do it – runs through codebases
like a naked Marxist through an overdressed stock exchange. It is not
enough for objects to be manufactured, managed and stripped of
behavioural responsibilities so they deliver little more than data: they must
also conform to interfaces and contracts. Depending on convention, there
is the me-centred I prefix, which is popular with millennial programmers,
or there is the contrapuntal summoning of supernatural creatures that hold
the promise of behaviour, the Impl suffix – a contraction of ImpWill.
The problem with these homeopathic naming conventions, where affixes
are continually added to a name to dilute its meaning, is not simply that
they reduce the informational content of information technology: they
project, coerce and reinforce an industrial and post-industrial view of the
world onto the semiotic space of our noosphere.
But it doesn’t have to be like this.
Where is nature? Where are the rural styles of coding? Instead of software
architecture, what of software agrarianism? It is possible to reclaim a more
rustic and ecologically balanced approach to code, whilst still ensuring
Teedy Deigh believes in sustainable development, which she
generally takes to mean a steady and sustainable flow of coffee,
energy drinks and ersatz potato snacks in exchange for lines of
code and a promise of no client contact (although it is not entirely
clear from which side this promise is extracted...).
32 | Overload | April 2015
sufficient verbosity to win the enterprize. And all this can be done without
setting foot outdoors!
Consider logging. This practice is rife in both tropical rainforests and
enterpricey systems. It is generally arbitrary and unsustainable and few
people are ever clear what the exact requirements are, so it spreads like a
cat meme. It would be simple enough to pass a log in only when it is
needed, or to define a need during construction rather than introducing a
global trade dependency, but it is clear that to be taken seriously by the
enterprison we must work closely with the existing architecture and start
by rebranding.
For familiarity’s sake we can keep the Log class, but where do logs come
from? The conventional answer is a LogFactory. But no, work the
metaphor: a Forest ! And how should they be managed? By a
LogManager – or by a Lumberjack? These should be defined in a
timber package, with a specialisation for SustainableForest –
which throws an IllegalLogging exception when overused – and a
specialisation for PoorlyManagedForest – which is deprecated with
immediate effect. Rather than write to a log, we can carve, and rather than
dispose of a log, we can fell it.
Such subtle shifts in style allow the preservation of an enterpies growth
model, but give developers the illusion of doing something worthwhile,
offering them a simulated engagement with nature, but without all the
nastiness of having to actually go outdoors. 