Which standard c++ classes cannot be reimplemented in c++?

c++, compiler-construction

Solution

`std::type_info` is a simple class, although populating it requires `typeinfo`: a compiler construct.

Likewise, exceptions are normal objects, but throwing exceptions requires compiler magic (where are the exceptions allocated?).

The question, to me, is "how close can we get to `std::initializer_list`s without compiler magic?"

Looking at wikipedia, `std::initializer_list<typename T>` can be initialized by something that looks a lot like an array literal. Let's try giving our `std::initializer_list<typename T>` a conversion constructor that takes an array (i.e., a constructor that takes a single argument of `T[]`):

namespace std {
     template<typename T> class initializer_list {
         T internal_array[];
         public:
         initializer_list(T other_array[]) : internal_array(other_array) { };

         // ... other methods needed to actually access internal_array
     }
}

Likewise, a class that uses a `std::initializer_list` does so by declaring a constructor that takes a single `std::initializer_list` argument -- a.k.a. a conversion constructor:

struct my_class {
    ...
    my_class(std::initializer_list<int>) ...
}

So the line:

 my_class m = {1, 2, 3};

Causes the compiler to think: "I need to call a constructor for `my_class`; `my_class` has a constructor that takes a `std::initializer_list<int>`; I have an `int[]` literal; I can convert an `int[]` to a `std::initializer_list<int>`; and I can pass that to the `my_class` constructor" (please read to the end of the answer before telling me that C++ doesn't allow two implicit user-defined conversions to be chained).

So how close is this? First, I'm missing a few features/restrictions of initializer lists. One thing I don't enforce is that initializer lists can only be constructed with array literals, while my `initializer_list` would also accept an already-created array:

int arry[] = {1, 2, 3};
my_class = arry;

Additionally, I didn't bother messing with rvalue references.

Finally, this class only works as the new standard says it should if the compiler implicitly chains two user-defined conversions together. This is specifically prohibited under normal cases, so the example still needs compiler magic. But I would argue that (1) the class itself is a normal class, and (2) the magic involved (enforcing the "array literal" initialization syntax and allowing two user-defined conversions to be implicitly chained) is less than it seems at first glance.

Problem

I was looking through the plans for C++0x and came upon `std::initializer_list` for implementing initializer lists in user classes. This class could not be implemented in C++ without using itself, or else using some "compiler magic". If it could, it wouldn't be needed since whatever technique you used to implement `initializer_list` could be used to implement initializer lists in your own class. What other classes require some form of "compiler magic" to work? Which classes are in the Standard Library that could not be implemented by a third-party library? Edit: Maybe instead of implemented, I should say instantiated. It's more the fact that this class is so directly linked with a language feature (you can't use initializer lists without `initializer_list`). A comparison with C# might clear up what I'm wondering about: IEnumerable and IDisposable are actually hard-coded into language features. I had always assumed C++ was free of this, since Stroustrup tried to make everything implementable in libraries. So, are there any other classes / types that are inextricably bound to a language feature.

Original source