Forward declare a standard container?

25,159

Solution 1

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?

Solution 2

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.

Solution 3

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.

Share:
25,159
Rob
Author by

Rob

C++, MFC, Win32, WTL, STL, Boost, HTML, CSS, JavaScript, Qt, Python, jQuery Mobile.

Updated on July 09, 2022

Comments

  • Rob
    Rob almost 2 years

    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?

  • Paul Kapustin
    Paul Kapustin over 15 years
    exactly what I just wanted to say
  • Haplo
    Haplo almost 14 years
    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.
  • Rob Kennedy
    Rob Kennedy almost 14 years
    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.
  • Potatoswatter
    Potatoswatter over 9 years
    "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 happen
  • underscore_d
    underscore_d about 7 years
    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.