Re: instantiating a template on an incomplete type?
* Kai-Uwe Bux:
Alf P. Steinbach wrote:
* Kai-Uwe Bux:
Alf P. Steinbach wrote:
* Kai-Uwe Bux:
Hendrik Schober wrote:
Bart van Ingen Schenau wrote:
Hendrik Schober wrote:
Hi,
can I instantiate a template on an incomplete type?
In general, yes.
<snip>
This compiles just fine using VC9 and Comeau (online), but ISTR that
there was a problem with this.
The standard containers have as requirement that they can only be
instantiated on complete types, but that requirement does not carry
over to templates in general.
Thanks. That's good news.
Now. Waitaminute. That is, I cannot create a class that has
a container of objects like itself as member?
class xyz;
typedef std::vector<xyz> xyz_list;
class xyz {
xyz_list more_of_mine;
};
Wasn't it that /some of the containers/ didn't support this,
but some did?!
Nope. None of the standard containers support that. You encounter
undefined behavior and no diagnostic is required.
Uhm, I think I'd like chapter and verse for that.
I am thinking of [17.4.3.6/1-2]:
In certain cases (replacement functions, handler functions, operations
on types used to instantiate standard library template components), the
C++ Standard Library depends on components supplied by a C + + program.
If these components do not meet their requirements, the Standard places
no requirements on the implementation.
In particular, the effects are undefined in the following cases:
...
? if an incomplete type (3.9) is used as a template argument when
instantiating a template component.
That seems to be the case for
#include <memory>
class Foo;
int main() { std::auto_ptr<Foo> p; }
although it may be argued that std::auto_ptr's more specific requirement
that 'delete p.get()' is well-formed means that it's OK with incomplete
type as long as it has a trivial destructor.
But the question for the xyz example above is, is std::vector<xyz> at all
instantiated, in the standard's meaning of that term for a template, in
that code?
This is, I think, what must be shown in order to invoke ?17.4.3.6/1-2, and
the point of my comment about apparently very "lazy" template
instantiation.
Bart von Ingen Schenau already pointed to [14.7.1/1].
Yes, that's the paragraph I referred to in my first article.
As for the remaining
question why a member declaration of a class requires a complete type, so
far I only have [9.2/2]:
A class is considered a completely-defined object type (3.9) (or complete
type) at the closing } of the class-specifier.
It seems hard to be complete with members of incomplete type.
Hm.
struct Foo;
struct Bar { Foo blah(); }; // Is OK :-)
At this point an object of type Bar can be instantiated, it's a complete type.
But the member routine Bar::blah cannot be called, so a complete type can have
members of incomplete type -- not hard at all! :-)
It's just that they cannot be used, and a member variable Bar::m of incomplete
type is used as soon as a Bar object is instantiated, or copied, whatever.
The problem seems therefore to be why a member variable Bar::m is considered
used just by being declared, as opposed to the Bar::blah routine. I don't know.
Testing with g++ and MSVC it doesn't seem to have anything to do with
automatically generated special member routines that might use a Bar::m.
Alternatively it may be that somewhere the standard spells out or implicitly
requires that a member variable (as opposed to routine) be of complete type?
[snip]
Cheers,
- Alf
--
Due to hosting requirements I need visits to <url: http://alfps.izfree.com/>.
No ads, and there is some C++ stuff! :-) Just going there is good. Linking
to it is even better! Thanks in advance!