Is there a deep reason why this should not work? Why not allowing the typedef to resolve the forward declaration as long as the sources match and as long as the ODR is followed?
A follow-up quesition is: Why is there no way to forward-declare a generic object type that is later defined to an object type?
With such a forward declaration one could already use pointers till the type is bound to an object type. Given this one were not forced to use reinterpret_cast or lots of code in such a situation.
The only reason I can think of is that one would have to extend the linkers to cope with forward-declarations.
Christoph Bartoschek wrote: > the following code does not work:
> class A; > class B {}; > typdef B A;
> Is there a deep reason why this should not work?
You mean, besides the fact that it makes no real sense to do that? You're not using 'A' between the forward-declaration and the typedef. So, why would you want to forward-declare it? Use an example closer to real life.
The main question is, what does it buy you?
> Why not allowing the
> typedef to resolve the forward declaration as long as the sources match and > as long as the ODR is followed?
There are slightly different requirements to the uses of class-id (or type-id) and typedef-name, although they may not be playing any significant roles in your cases. For example, you can't use "class T" if 'T' is a typedef-name, even if the underlying type is a class. I am not sure why that is, though. Ask in comp.c++.std for the rationale behind that limitation in [basic.lookup.elab/2]. There are other examples of that in the Standard, probably. Look 'em up.
> A follow-up quesition is: Why is there no way to forward-declare a generic > object type that is later defined to an object type?
Most likely because the more definitive the declaration, the easier it is for the compiler to analyse the rest of the code that uses that symbol and the more efficient and less ambiguous the rules are... My speculation, of course - I never attempted to write a compiler from such a complex language like C++.
> With such a forward declaration one could already use pointers till the type > is bound to an object type. Given this one were not forced to use > reinterpret_cast or lots of code in such a situation.
> The only reason I can think of is that one would have to extend the linkers > to cope with forward-declarations.
Maybe. Your guess is likely better than mine.
V -- Please remove capital 'A's when replying by e-mail I do not respond to top-posted replies, please don't ask
> Christoph Bartoschek wrote: >> the following code does not work:
>> class A; >> class B {}; >> typdef B A;
>> Is there a deep reason why this should not work?
> You mean, besides the fact that it makes no real sense to do that?
It would make perfect sense to do that, and the miss of such feature is pretty damn painful.
> You're not using 'A' between the forward-declaration and the typedef.
Come on, now ;). Look up the zillion old threads asking why one can't say
class std::string; or void foo(class std::string const & str);
not including <string> in the header and write all the declarations riding the incomplete type -- then when definition or use is due include the header.
> So, why would you want to forward-declare it? Use an example closer to > real life.
people struggling for separation of interfaces and cut dependencies could quote a big deal of code matching the problem. It breaks transparency badly, suppose you had the code working with the incomplete type, than at some point of time, where your class had a separate implementation in a separate file.
Then you observe that the class is generic enough, and can be made into a template, the original turining to some Templ<T> that can be put back as a typedef. And then notice, that the forward declaration is not compatible.
I guess the reason lies with some historic feature of the linkers and name mangling. Too bad it got not covered ever since. C++0x fixes the related problem for enums.
On Nov 9, 1:28 pm, Victor Bazarov <v.Abaza...@comAcast.net> wrote:
> Christoph Bartoschek wrote: > > the following code does not work: > > class A; > > class B {}; > > typedef B A; > > Is there a deep reason why this should not work?
Try interposing some additional declarations:
class A; void f(A*); class B{}; void f(B*); typedef B A;
> You mean, besides the fact that it makes no real sense to do > that? You're not using 'A' between the forward-declaration > and the typedef. So, why would you want to forward-declare > it? Use an example closer to real life. > The main question is, what does it buy you? > > Why not allowing the typedef to resolve the forward > > declaration as long as the sources match and as long as the > > ODR is followed? > There are slightly different requirements to the uses of > class-id (or type-id) and typedef-name, although they may not > be playing any significant roles in your cases. For example, > you can't use "class T" if 'T' is a typedef-name, even if the > underlying type is a class. I am not sure why that is, > though. Ask in comp.c++.std for the rationale behind that > limitation in [basic.lookup.elab/2]. There are other examples > of that in the Standard, probably. Look 'em up. > > A follow-up quesition is: Why is there no way to > > forward-declare a generic object type that is later defined > > to an object type? > Most likely because the more definitive the declaration, the > easier it is for the compiler to analyse the rest of the code > that uses that symbol and the more efficient and less > ambiguous the rules are... My speculation, of course - I > never attempted to write a compiler from such a complex > language like C++.
The problem here is simple: you can declare and define pointers to an incomplete type. So the compiler has to either know the exact type, or know that it is a class type, so that it can know the size and the representation of the pointer. You can forward declare that the type is a class type, but you can't forward declare that it will be some arbitrary type.
> > With such a forward declaration one could already use > > pointers till the type is bound to an object type. Given > > this one were not forced to use reinterpret_cast or lots of > > code in such a situation. > > The only reason I can think of is that one would have to > > extend the linkers to cope with forward-declarations. > Maybe. Your guess is likely better than mine.
The problem is principly because there exist (or have existed) systems on which pointers to different types have different sizes and representations.