By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
458,127 Members | 1,237 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 458,127 IT Pros & Developers. It's quick & easy.

Calling container constructor explicitly

P: n/a
I'm trying to write some code that calls the constructors of STL
containers explicitly, and I can't get it to compile. A sample program
is below. One compiler complains about the last two lines (the map
constructor calls), saying that I'm trying to take the address of a
constructor. Another compiler complains about all four of the last
lines, just saying "invalid use of class". What is the correct syntax
for calling a container constructor explicitly?

You're probably wondering why I'm not calling "new" instead of malloc
and the constructor. It's because what I really need to do is to call
a proprietary memory allocation function (i.e., not malloc) and then
call a parameterized constructor on the returned space. So neither
"new" nor "placement new" will work for me.

Thanks for the help!

- Dave
#include <vector>
#include <map>
#include <cstdlib>

int
main()
{
typedef std::vector<int VecType;
typedef std::map<int, intMapType;

VecType v, *vp;
MapType m, *mp;

vp = (VecType *)malloc(sizeof(VecType));
mp = (MapType *)malloc(sizeof(MapType));

// call constructors
v.VecType::vector();
vp->VecType::vector();
m.MapType::map();
mp->MapType::map();
}

Jul 16 '06 #1
Share this Question
Share on Google+
6 Replies


P: n/a
* daveb:
I'm trying to write some code that calls the constructors of STL
containers explicitly, and I can't get it to compile.
The following is an implicit constructor call ("implicit" means "implied
or understood though not directly expressed"):

std::vector<intv;

The following is an explicit constructor call ("explicit" means "fully
and clearly expressed; leaving nothing implied"):

std::vector<int>();

The last one creates a temporary; see the FAQ.

A sample program
is below. One compiler complains about the last two lines (the map
constructor calls), saying that I'm trying to take the address of a
constructor. Another compiler complains about all four of the last
lines, just saying "invalid use of class". What is the correct syntax
for calling a container constructor explicitly?
In general, supplying a constructor argument list after a type
specification is the correct syntax for calling a constructor
explicitly. But that's not a formal view: it's just a summary of the
effect of the formal syntax rules. Also, note that the opposite does
not hold: int() constructs the int value 0, but int has no constructor.

You're probably wondering why I'm not calling "new" instead of malloc
and the constructor. It's because what I really need to do is to call
a proprietary memory allocation function (i.e., not malloc) and then
call a parameterized constructor on the returned space. So neither
"new" nor "placement new" will work for me.
Placement new is exactly for that.

But it's a rather silly thing, nay, STRONGERWORD thing, to do.

A vector object by itself takes up just a few bytes. The contents are
typically allocated separately. To take charge of the allocation for
vector contents you need to specify an allocator type in the type
definition.

#include <vector>
#include <map>
#include <cstdlib>

int
main()
{
typedef std::vector<int VecType;
typedef std::map<int, intMapType;

VecType v, *vp;
At this point v has been constructed and vp is uninitialized pointer.

MapType m, *mp;

vp = (VecType *)malloc(sizeof(VecType));
mp = (MapType *)malloc(sizeof(MapType));

// call constructors
v.VecType::vector();
vp->VecType::vector();
Syntax error.

The way to call constructors on raw storage is to use placement new, but
see above: it's STRONGERWORD for std::vector, check out allocators.
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jul 16 '06 #2

P: n/a
daveb wrote:
What is the correct syntax for calling a container constructor explicitly?
The same as for any other class: none.
You're probably wondering why I'm not calling "new" instead of malloc
and the constructor. It's because what I really need to do is to call
a proprietary memory allocation function (i.e., not malloc) and then
call a parameterized constructor on the returned space. So neither
"new" nor "placement new" will work for me.
Strange. "placement new" is habitually used for that.

If you want that the contained objects, not the container object itself, use
your allocation function, write an adequate allocator and use it.

--
Salu2
Jul 16 '06 #3

P: n/a
daveb wrote:
I'm trying to write some code that calls the constructors of STL
containers explicitly, and I can't get it to compile. A sample program
is below. One compiler complains about the last two lines (the map
constructor calls), saying that I'm trying to take the address of a
constructor. Another compiler complains about all four of the last
lines, just saying "invalid use of class". What is the correct syntax
for calling a container constructor explicitly?
That depends on what you mean by calling the constructor explictly. The
standard reserves this language for the function notation of a type
conversion like

std::string( "hello world" );

Despite that, placement new is what is semantically closest to calling a
constructor.
You're probably wondering why I'm not calling "new" instead of malloc
and the constructor. It's because what I really need to do is to call
a proprietary memory allocation function (i.e., not malloc) and then
call a parameterized constructor on the returned space. So neither
"new" nor "placement new" will work for me.
Huh? Isn't this exactly what placement new is doing: construct an object at
a specified location in memory by invoking the constructor appropriate for
the given arguments?
>
Thanks for the help!

- Dave
#include <vector>
#include <map>
#include <cstdlib>

int
main()
{
typedef std::vector<int VecType;
typedef std::map<int, intMapType;

VecType v, *vp;
MapType m, *mp;

vp = (VecType *)malloc(sizeof(VecType));
mp = (MapType *)malloc(sizeof(MapType));

// call constructors
v.VecType::vector();
vp->VecType::vector();
m.MapType::map();
mp->MapType::map();
}

That won't fly as constructors don't have names, are not found by name
lookup and therefore cannot be called like member functions.

What about:

VecType v;
VecType* vp = (VecType *)malloc(sizeof(VecType));
new ( vp ) VecType ();

MapType m;
MapType* mp = (MapType *)malloc(sizeof(MapType));
new ( mp ) MapType ();
Best

Kai-Uwe
Jul 16 '06 #4

P: n/a
daveb wrote:
>
You're probably wondering why I'm not calling "new" instead of malloc
and the constructor. It's because what I really need to do is to call
a proprietary memory allocation function (i.e., not malloc) and then
call a parameterized constructor on the returned space. So neither
"new" nor "placement new" will work for me.
I'm not sure why you jump to the conclusion placement new will not
work. It appears to be exactly what you want.

You can't call constructors PERIOD. The best you can do is create
objects with a different allocation function (i.e., placement new).

You do know that the memory used by a standard container itself
is tiny compared with the memory for the contained objects which
you probably need to write an allocation function for as well.
Jul 16 '06 #5

P: n/a
My thanks to everyone who responded. I was under the impression that
placement new could be used only to call an object's *default*
constructor. But I infer from the code that Kai-Uwe provided that
parameterized constructors can be called by providing the parameters
within parentheses at the end of the statement. If so, (as most of you
noted) that's exactly what I need.

BTW, this is embedded firmware. I need the proprietary memory
allocator because the container and its contents must reside in a
"persistent" area of memory that is not initialized at boot time. I
already intended to provide a custom allocator to the container, but
this custom allocator will be called only for the *contents* of the
container, correct? I also need the container itself to live in the
persistent region of memory.

- Dave

Jul 17 '06 #6

P: n/a
* Julián Albo:
daveb wrote:
>What is the correct syntax for calling a container constructor explicitly?

The same as for any other class: none.
Do not perpetuate urban myths, please.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jul 17 '06 #7

This discussion thread is closed

Replies have been disabled for this discussion.