Calling container constructor explicitly

D

daveb

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, int> MapType;

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();
}
 
A

Alf P. Steinbach

* 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<int> v;

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, int> MapType;

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.
 
?

=?ISO-8859-15?Q?Juli=E1n?= Albo

daveb said:
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.
 
K

Kai-Uwe Bux

daveb said:
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, int> MapType;

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
 
R

Ron Natalie

daveb said:
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.
 
D

daveb

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,778
Messages
2,569,605
Members
45,237
Latest member
AvivMNS

Latest Threads

Top