472,363 Members | 2,047 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,363 software developers and data experts.

Safe union of std::vectors

I'd like to do something along these lines:

struct foo
{
int i1_;
int i2_;
};

struct bar
{
double d1_;
double d2_;
};

typedef std::vector<foo> vectorFoo;
typedef std::vector<bar> vectorBar;

union vectorAll
{
vectorFoo foo_;
vectorBar bar_;
};

static vectorAll myVectorAll;
....
foo myFoo;
myVectorAll.foo_.push_back(myFoo);
myVectorAll.foo_.clear();
....
bar myBar;
myVectorAll.bar_.push_back(myBar);
myVectorAll.bar_.clear();

But a) I'm fairly sure that this isn't valid C++ because std::vector
must have a constructor, b) it seems very unsafe. and c) it precludes
sensible requirements such as clearing myVectorAll without knowing what
type is in it. (Intuitively one might want to be able to do a
myVectorAll.clear());

Given that one of my target compilers is too uncompliant to compile
boost, I can't use boost::any for this. What are my other options?

--
Simon Elliott http://www.ctsn.co.uk
Jul 23 '05 #1
5 7888
"Simon Elliott" <Simon at ctsn.co.uk> wrote in message
news:41***********************@news.gradwell.net.. .
I'd like to do something along these lines:

struct foo
{
int i1_;
int i2_;
};

struct bar
{
double d1_;
double d2_;
};

typedef std::vector<foo> vectorFoo;
typedef std::vector<bar> vectorBar;

union vectorAll
{
vectorFoo foo_;
vectorBar bar_;
};

static vectorAll myVectorAll;
...
foo myFoo;
myVectorAll.foo_.push_back(myFoo);
myVectorAll.foo_.clear();
...
bar myBar;
myVectorAll.bar_.push_back(myBar);
myVectorAll.bar_.clear();

But a) I'm fairly sure that this isn't valid C++ because std::vector
must have a constructor,
It's invalid because std::vector *does* have a (non-trivial)
constructor (as well as other precluded member functions).
(C&V below)
b) it seems very unsafe.
Well, I suppose it you were able to convince a compiler
to create code for it, it would very likely be 'unsafe'. :-)
and c) it precludes
sensible requirements such as
Such as violating the standard's rules. :-)
clearing myVectorAll without knowing what
type is in it. (Intuitively one might want to be able to do a
myVectorAll.clear());
I wouldn't intiut that because the your union has no member
functions.
Given that one of my target compilers is too uncompliant to compile
boost, I can't use boost::any for this. What are my other options?


Don't use a union. :-) How about a function template?
(Of course that's just a guess, without knowing more
about what you're trying to do.)

ISO/IEC 14882:1998(E)

9.5 Unions

1 In a union, at most one of the data members can be active
at any time, that is, the value of at most one of the data
members can be stored in a union at any time. [Note: one
special guarantee is made in order to simplify the use of
unions: If a POD*-union contains several POD*-structs that
share a common initial sequence (9.2), and if an object of
this POD*-union type contains one of the POD*-structs, it is
permitted to inspect the common initial sequence of any of
POD*struct members; see 9.2. ] The size of a union is suffi*-
cient to contain the largest of its data members. Each data
member is allocated as if it were the sole member of a struct.
A union can have member functions (including constructors
and destructors), but not virtual (10.3) functions. A union
shall not have base classes. A union shall not be used as a
base class. An object of a class with a non*-trivial constructor
(12.1), a non-*trivial copy constructor (12.8), a non*-trivial
destructor (12.4), or a non-*trivial copy assignment operator
(13.5.3, 12.8) cannot be a member of a union, nor can an
array of such objects. If a union contains a static data
member, or a member of reference type, the program is ill-*formed.
-Mike
Jul 23 '05 #2

Simon Elliott wrote:
I'd like to do something along these lines:

struct foo {...}
struct bar {...}
typedef std::vector<foo> vectorFoo;
typedef std::vector<bar> vectorBar;

union vectorAll
{
vectorFoo foo_;
vectorBar bar_;
};

static vectorAll myVectorAll;
...
foo myFoo;
myVectorAll.foo_.push_back(myFoo);
myVectorAll.foo_.clear();
...
bar myBar;
myVectorAll.bar_.push_back(myBar);
myVectorAll.bar_.clear();

But a) I'm fairly sure that this isn't valid C++ because std::vector
must have a constructor, b) it seems very unsafe. and c) it precludes
sensible requirements such as clearing myVectorAll without knowing what type is in it. (Intuitively one might want to be able to do a
myVectorAll.clear());

Given that one of my target compilers is too uncompliant to compile
boost, I can't use boost::any for this. What are my other options?


The logical solution is probably to wrap your own vector class
around a union of two pointers, a Foo* and a Bar*. You can use a
shared size member, so you can implement empty() without
differentiating which elements there aren't ;) For most operations
you will have to use a tag, though.

You'd have to add your own push_back overloads, your own iterators,
a foo_begin() and a bar_begin() but it's not too difficult.

BTW, if you're targetting multiple platforms and one is very out
of date, you might want to consider Comeau.

HTH,
Michiel Salters

Jul 23 '05 #3
Simon Elliott wrote:
I'd like to do something along these lines:

struct foo
{
int i1_;
int i2_;
};

struct bar
{
double d1_;
double d2_;
};

typedef std::vector<foo> vectorFoo;
typedef std::vector<bar> vectorBar;

union vectorAll
{
vectorFoo foo_;
vectorBar bar_;
};

static vectorAll myVectorAll;
...
foo myFoo;
myVectorAll.foo_.push_back(myFoo);
myVectorAll.foo_.clear();
...
bar myBar;
myVectorAll.bar_.push_back(myBar);
myVectorAll.bar_.clear();

[...]
Given that one of my target compilers is too uncompliant to compile
boost, I can't use boost::any for this. What are my other options?


Perhaps something like the following might do the job:

class FooBarVector
{
enum VectorType { NONE, FOO, BAR };
public:
FooBarVector() : type_(NONE) { };

~FooBarVector() {
switch(type_) {
case FOO: delete v_.foo_; break;
case BAR: delete v_.bar_; break;
}
type_ = NONE;
}

vectorFoo& foo(){
if (type_ == BAR)
delete v_.bar_;
if (type_ != FOO) {
v_.foo_ = new vectorFoo();
type_ = FOO;
}
return *(v_.foo_);
}

vectorBar& bar(){
if (type_ == FOO)
delete v_.foo_;
if (type_ != BAR) {
v_.bar_ = new vectorBar();
type_ = BAR;
}
return *(v_.bar_);
}
private:
union {
vectorFoo *foo_;
vectorBar *bar_;
} v_;

VectorType type_;
};

// ...
static FooBarVector v;
// ...
Foo myFoo;
v.foo().push_back(myFoo);
v.foo().clear();
// ...
Bar myBar;
v.bar().push_back(myBar);
v.bar().clear();
// ...

As an alternative, you can throw an exception, if foo() is called with
an non-empty bar-Vector (and vice versa).

greetings
Martin
Jul 23 '05 #4
On 02/02/2005, msalters wrote:
The logical solution is probably to wrap your own vector class
around a union of two pointers, a Foo* and a Bar*. You can use a
shared size member, so you can implement empty() without
differentiating which elements there aren't ;) For most operations
you will have to use a tag, though.

You'd have to add your own push_back overloads, your own iterators,
a foo_begin() and a bar_begin() but it's not too difficult.
Yes. I was hoping for a solution that didn't involve vectors of
pointers though.
BTW, if you're targetting multiple platforms and one is very out
of date, you might want to consider Comeau.


I'd like to drop support for BCB3 but can't at the moment. I'm quite
interested in adding Comeau to the list of supported compilers at some
point.

--
Simon Elliott http://www.ctsn.co.uk
Jul 23 '05 #5

Simon Elliott wrote:
On 02/02/2005, msalters wrote:
The logical solution is probably to wrap your own vector class
around a union of two pointers, a Foo* and a Bar*. You can use a
shared size member, so you can implement empty() without
differentiating which elements there aren't ;) For most operations
you will have to use a tag, though.

You'd have to add your own push_back overloads, your own iterators,
a foo_begin() and a bar_begin() but it's not too difficult.
Yes. I was hoping for a solution that didn't involve vectors of
pointers though.


It's not a vector of pointers, just

template< typename T1, typename T2 >
class bi_vector
{
union {
T1* t1_array;
T2* t2_array;
} data;
size_t size;
enum { t1_used, t2_used } type_in_data;
public:
// ...
};
If you want to save memory, you could use a signed integer type
for size, with size > 0 meaning size T1 objects and size < 0
meaning -size T2 objects. Not worth the price if these vectors
are rare, of course.

HTH,
Michiel Salters
BTW, if you're targetting multiple platforms and one is very out
of date, you might want to consider Comeau.


I'd like to drop support for BCB3 but can't at the moment. I'm quite
interested in adding Comeau to the list of supported compilers at

some point.

--
Simon Elliott http://www.ctsn.co.uk


Jul 23 '05 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

9
by: ree | last post by:
Unlike arrays I am having problems accessing objects placed in a vector I have a vector of objects called Semesters Each Semester has its own vector of Subjects. I am having problems...
5
by: Pratyush | last post by:
Hi, Suppose there is a vector of objects of class A, i.e., std::vector<A> vec_A(N); The class A satisifies all the STL vector requirements. Now I wish to add some attributes for each of the...
7
by: Jerry Krinock | last post by:
I've declared a class that has some std::vector data members like this: class MyClass { public: ... std::vector<Apples> apples ; ... private: ...
7
by: Martin Magnusson | last post by:
I'm having trouble clearing and resizing a static std::vector of std::vectors (segmentation fault). Is it OK to call clear() and resize() on a static attribute? My code is similar to the one posted...
21
by: Peter Olcott | last post by:
I got the previous alias to std::vector working, and found that it takes up the space of a pointer. I want to find a way to do an alias to a std::vector that does not take up any space. Is there...
7
by: Marcus Kwok | last post by:
I am utilizing a std::vector<int>, but due to a platform-specific reason (Managed C++, but this is irrelevant), in order to include it as a member of a class, I have to work with a pointer to it. ...
5
by: arnuld | last post by:
/* C++ Primer 4/e * STATEMENT * given 2 vectors of integers, write a programme to determine whether one vector * is the prefix of the other vector e.g. if 1st vector has elements...
8
by: Bryan | last post by:
Hello all. I'm fairly new to c++. I've written several programs using std::vectors, and they've always worked just fine. Until today. The following is a snippet of my code (sorry, can't...
3
by: Carter | last post by:
I am currently writing some code where I have a list of objects with a maximum occupancy of 4. I have been employing std::vector for this but I was wondering how much overhead is involved. Is it...
2
by: Kemmylinns12 | last post by:
Blockchain technology has emerged as a transformative force in the business world, offering unprecedented opportunities for innovation and efficiency. While initially associated with cryptocurrencies...
0
by: antdb | last post by:
Ⅰ. Advantage of AntDB: hyper-convergence + streaming processing engine In the overall architecture, a new "hyper-convergence" concept was proposed, which integrated multiple engines and...
0
by: AndyPSV | last post by:
HOW CAN I CREATE AN AI with an .executable file that would suck all files in the folder and on my computerHOW CAN I CREATE AN AI with an .executable file that would suck all files in the folder and...
0
Oralloy
by: Oralloy | last post by:
Hello Folks, I am trying to hook up a CPU which I designed using SystemC to I/O pins on an FPGA. My problem (spelled failure) is with the synthesis of my design into a bitstream, not the C++...
0
BLUEPANDA
by: BLUEPANDA | last post by:
At BluePanda Dev, we're passionate about building high-quality software and sharing our knowledge with the community. That's why we've created a SaaS starter kit that's not only easy to use but also...
0
by: Rahul1995seven | last post by:
Introduction: In the realm of programming languages, Python has emerged as a powerhouse. With its simplicity, versatility, and robustness, Python has gained popularity among beginners and experts...
1
by: Ricardo de Mila | last post by:
Dear people, good afternoon... I have a form in msAccess with lots of controls and a specific routine must be triggered if the mouse_down event happens in any control. Than I need to discover what...
0
by: Johno34 | last post by:
I have this click event on my form. It speaks to a Datasheet Subform Private Sub Command260_Click() Dim r As DAO.Recordset Set r = Form_frmABCD.Form.RecordsetClone r.MoveFirst Do If...
1
by: ezappsrUS | last post by:
Hi, I wonder if someone knows where I am going wrong below. I have a continuous form and two labels where only one would be visible depending on the checkbox being checked or not. Below is the...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.