This reminds me of the list of advanced C++ questions I once compiled (based on things I have actually had to learn):
1) STL containers have, among others, two special constructors: One which
takes an integral and a reference to the value type (to initialize the
container with the specified amount of values) and another which takes two
iterators (to initialize the container with a value range specified by those
iterators). In other words, the containers will have two constructors in the
form:
Containter::Container(size_type amount, const value_type& value);
template<typename Iterator>
Container::Container(Iterator startIter, Iterator endIter);
Suppose you do this:
std::vector<int> container(10, 5);
In principle that constructor call matches both of the above constructors.
The compiler will choose the one which matches best. In this case the
constructor taking two iterators will be a best match (because both
parameters are of the exact same type). In other words, the "wrong"
constructor will be called (yes, this does actually happen). However, the
STL containers still manage to do the right thing (rather than giving a
compiler error because ints are not iterators). How?
2) Give an example code where using static_cast gives a compiler error,
while using dynamic_cast compiles and works ok. The only difference between
the two cases is the keyword, otherwise the codes must be the same. Also
explain why this is so.
(And no, this problem does not involve precompiler macro trickery or
anything of the sorts. That's not what this problem is asking. It's about
the semantics of static_cast vs. dynamic_cast.)
3) Explain the concept of 'placement new' and why/when it can be useful.
Give an example of an actual usage in the standard library. Also explain
how objects constructed in this way can be destroyed properly.
4) STL containers support user-defined memory allocators (specified as
class template parameter, instances of these allocators being given as
constructor parameter). By default, instantiating eg. a list of integers
is completely equivalent to this:
std::list<int, std::allocator<int> > theList((std::allocator<int>()));
The std::list is given an allocator of type int (that is, an allocator
which is configured to allocate elements of type int; among other things,
this makes it have a function for constructing objects of that type).
However, std::list will not allocate objects of type int. Instead, it
will allocate objects of an internal type (usually some struct which
contains the int and two pointers as members). However, it was not given
an allocator which was configured to allocate objects of that internal type.
Thus it cannot use the given allocator directly for allocating those objects.
How is this problem solved within STL allocators?
5) Notice how in the previous example a set of extra parentheses was used
in the constructor call. This was not a mistake. Explain why those extra
parentheses are necessary.