This question was investigated in a Technical Report on C++ Performance. See appendix D.3 for the Stepanove Abstraction Penalty Benchmark. To quote
The structure of the benchmark is really quite simple. It adds 2000
doubles in an array 25000 times. It does it in 13 different ways that
introduce more and more abstract ways of doing it:
0 - uses simple
Fortran-like for loop.
1 - 12 use STL style accumulate template
function with plus function object.
1, 3, 5, 7 ,9, 11 use doubles.
2, 4, 6, 8, 10, 12 use Double - double wrapped in a class.
1, 2 - use
regular pointers.
3, 4 - use pointers wrapped in a class.
5, 6 - use
pointers wrapped in a reverse-iterator adaptor.
7, 8 - use wrapped
pointers wrapped in a reverse-iterator adaptor.
9, 10 - use pointers
wrapped in a reverse-iterator adaptor wrapped in a reverse-iterator
adaptor.
11, 12 - use wrapped pointers wrapped in a reverse-iterator
adaptor wrapped in a reverse-iterator adaptor.
Output on Ideone: the abstraction penalty (geometric mean of all 13 tests) for a modern compiler (gcc 4.5.1) is less than 1%.