dimanche 6 mai 2018

Incomplete type is not allowed in a class, but is allowed in a class template

The following is invalid code:

struct foo {
    struct bar;
    bar x;        // error: field x has incomplete type
    struct bar{ int value{42}; };
};

int main() { return foo{}.x.value; }

This is quite clear, as foo::bar is considered incomplete at the point where foo::x is defined.

However, there seems to be a "workaround" which makes the same class definition valid:

template <typename = void>
struct foo_impl {
    struct bar;
    bar x;        // no problems here
    struct bar{ int value{42}; };
};

using foo = foo_impl<>;

int main() { return foo{}.x.value; }

This works with all major compilers. I have three questions about this:

  1. Is this indeed valid C++ code, or just a quirk of the compilers?
  2. If it is valid code, is there a paragraph in the C++ standard that deals with this exception?
  3. If it is valid code, why is the first version (without template) considered invalid? If the compiler can figure out the second option, I don't see a reason why it wouldn't be able to figure out the first one.

Aucun commentaire:

Enregistrer un commentaire