Forward declare a standard container?
Asked Answered
B

3

52

Is it possible to forward declare an standard container in a header file? For example, take the following code:

#include <vector>

class Foo
{
private:
    std::vector<int> container_;
    ...
};

I want to be able to do something like this:

namespace std
{
    template <typename T> class vector;
}

class Foo
{
private:
    std::vector<int> container_;
    ...
};

Can this be done?

Booking answered 20/11, 2008 at 23:58 Comment(0)
A
37

Declaring vector in the std namespace is undefined behavior. So, your code might work, but it also might not, and the compiler is under no obligation to tell you when your attempt won't work. That's a gamble, and I don't know that avoiding the inclusion of a standard C++ header is worth that.

See the following comp.std.c++.moderated discussion:

forward declaring std::vector. Works, but is it legal and standard compliant?

Aerobiology answered 21/11, 2008 at 0:30 Comment(3)
I followed your link to the discussion, but the people do not seem to be coming to an conclusion. Apparently, the stl implementation must not add any template parameters to the standard containers. hence, it should be allowed to forward declare the template.Overstuffed
It's undefined, @Haplo. If the implementation you're using chooses to define the behavior beyond what the standard says, that's great, but it's still undefined, so your code won't be portable. The conclusion (judging from statements left unchallenged) is that the standard should allow it, but doesn't, and that there are two workarounds: Wrap the standard types in forward-declared user structs, or just bite the bullet and include the standard header. The latter is easy to do.Aerobiology
"Statements left unchallenged" on Usenet are hardly an authoritative source. But, Jerry Coffin is right when he quotes [namespace.std]/1. In practice, if your compiler diagnoses namespace std declarations in non-system headers, or if your standard library is not implemented in C++, then you could have a problem, but those things never happenContinuation
D
18

I don't think so because the compiler would have no way of knowing how much space to allocate for the container_ object. At best you could do:

std::vector<int> *container_;

and new it in the constructor, since the compiler knows the size of a pointer.

Dori answered 21/11, 2008 at 0:0 Comment(2)
exactly what I just wanted to sayFettle
Right, but that's a problem with all forward-declarations, not specifc to those in namespace std. So it answers the real question, not the one OP asked. :P We simply cannot forward-declare something and then instantiate it by value, for obvious reasons.Toad
I
13

Apart from what the others said, you may find it useful to know that there is a sanctioned way of forward-declaring iostreams and some related templates: The header <iosfwd>. It would be useful if the standard had more such headers.

Ibnsina answered 13/10, 2010 at 10:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.