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

5647 views
Skip to first unread message

Firkraag

unread,
Oct 27, 2007, 9:10:53 PM10/27/07
to
namespace std {
template <typename T> class allocator;
template <typename T, typename A> class vector;
}


struct Foo
{
void bar(std::vector<int, std::allocator<int> > const& v);
};

#include <vector>
#include <iterator>
#include <algorithm>
#include <iostream>

using namespace std;

void Foo::bar(std::vector<int> const& v)
{
copy(v.begin(), v.end(), ostream_iterator<int, char>(cout, " "));
}


int main()
{
vector<int> v;
v.push_back(3);
v.push_back(4);

Foo foo;
foo.bar(v);
}


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Jerry Coffin

unread,
Oct 28, 2007, 3:22:29 AM10/28/07
to
In article <1193505682.3...@k79g2000hse.googlegroups.com>,
firkr...@tlen.pl says...

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

According to section 17.4.3.1.3/1: "Each name declared as an object with
external linkage in a header is reserved to the implementation to
designate that library object with external linkage, both in namespace
std and in the global namespace."

And according to section 17.4.3.1/3: "If the program declares or defines
a name in a context where it is reserved, other than as explicitly
allowed by this clause, the behavior is undefined."

I can't find anything to explicitly allow you to declare std::vector, so
I believe the code has undefined behavior.

--
Later,
Jerry.

The universe is a figment of its own imagination.

Pete Becker

unread,
Oct 28, 2007, 2:04:05 PM10/28/07
to
On 2007-10-27 21:22:29 -0400, Jerry Coffin <jco...@taeus.com> said:

> In article <1193505682.3...@k79g2000hse.googlegroups.com>,
> firkr...@tlen.pl says...
>> namespace std {
>> template <typename T> class allocator;
>> template <typename T, typename A> class vector;
>> }
>
> According to section 17.4.3.1.3/1: "Each name declared as an object with
> external linkage in a header is reserved to the implementation to
> designate that library object with external linkage, both in namespace
> std and in the global namespace."
>
> And according to section 17.4.3.1/3: "If the program declares or defines
> a name in a context where it is reserved, other than as explicitly
> allowed by this clause, the behavior is undefined."
>
> I can't find anything to explicitly allow you to declare std::vector, so
> I believe the code has undefined behavior.

And, in particular, standard library implementations are allowed to add
extra template parameters to the standard templates, provided those
parameters have default values. So the forward declaration given above
may be wrong.

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)

Daniel Krügler

unread,
Oct 28, 2007, 9:23:52 PM10/28/07
to
On 28 Okt., 19:04, Pete Becker <p...@versatilecoding.com> wrote:
> And, in particular, standard library implementations are allowed to add
> extra template parameters to the standard templates, provided those
> parameters have default values. So the forward declaration given above
> may be wrong.

Please correct me, if I'm wrong here, but I think according to
the resolution of

http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#94

it seems that it is *not* allowed for a library to do so, or
have I misunderstood something here?

Thanks and Greetings from Bremen,

Daniel

--

Vidar Hasfjord

unread,
Oct 28, 2007, 9:30:20 PM10/28/07
to
On Oct 28, 7:22 am, Jerry Coffin <jcof...@taeus.com> wrote:
> I can't find anything to explicitly allow you to declare std::vector, so
> I believe the code has undefined behavior.

Which means that ideally the standard should provide these forward
declarations in a header, I guess? Or is there a client solution to
this problem that is satisfactory? Or is the potential benefits from
not having to include the header deemed insignificant?

A simple typedef cannot be forward-declared, but obviously you could
encapsulate the std container inside a user type:

// Client header

struct std_vector;

struct Foo
{
void bar (std_vector const& v);
};

// Client implementation

#include <vector>
#include <iterator>
#include <algorithm>
#include <iostream>

using namespace std;

struct std_vector
{
vector <int> v;
};

void Foo::bar (std_vector const& v)
{
copy (v.v.begin (), v.v.end (),


ostream_iterator <int, char> (cout, " "));
}

int main()
{
// By exploiting initialization lists
// we avoid duplicating constructors.

int k [] = {3, 4};
std_vector v = {vector <int> (k, k + 2)};

Foo foo;
foo.bar (v);
}

Regards,
Vidar Hasfjord


--

Pete Becker

unread,
Oct 29, 2007, 5:41:21 PM10/29/07
to
On 2007-10-28 15:23:52 -0400, Daniel Krügler
<daniel....@googlemail.com> said:

> On 28 Okt., 19:04, Pete Becker <p...@versatilecoding.com> wrote:
>> And, in particular, standard library implementations are allowed to add
>> extra template parameters to the standard templates, provided those
>> parameters have default values. So the forward declaration given above
>> may be wrong.
>
> Please correct me, if I'm wrong here, but I think according to
> the resolution of
>
> http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#94
>
> it seems that it is *not* allowed for a library to do so, or
> have I misunderstood something here?
>

You're right. Looks like I remembered it wrong.

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)

[ See http://www.gotw.ca/resources/clcm.htm for info about ]

Hyman Rosen

unread,
Oct 29, 2007, 5:41:21 PM10/29/07
to
Vidar Hasfjord wrote:
> Or is the potential benefits from not having to include the
> header deemed insignificant?

Yes, that.

Reply all
Reply to author
Forward
0 new messages