473,769 Members | 1,723 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

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(myF oo);
myVectorAll.foo _.clear();
....
bar myBar;
myVectorAll.bar _.push_back(myB ar);
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.cle ar());

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 8149
"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(myF oo);
myVectorAll.foo _.clear();
...
bar myBar;
myVectorAll.bar _.push_back(myB ar);
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.cle ar());
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(myF oo);
myVectorAll.foo _.clear();
...
bar myBar;
myVectorAll.bar _.push_back(myB ar);
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.cle ar());

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(myF oo);
myVectorAll.foo _.clear();
...
bar myBar;
myVectorAll.bar _.push_back(myB ar);
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_ba ck(myFoo);
v.foo().clear() ;
// ...
Bar myBar;
v.bar().push_ba ck(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
3904
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 accssing attributes of the a subject given a particular semester. Can someone help me out with the syntax
5
3417
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 objects in the vector vec_A. Suppose there are K attributes to be added. For each of the attributes I define K vectors of appropriate types. Say, the attributes have types type1, type2, ..., typeK. So I define std::vector<type1> attr1(vec_A.size());
7
5700
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
3717
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 below. The code below works, though. My original code crashes on the second call to X::f(). My question is: is this code valid, or is it just a coincidence that it doesn't crash?
21
2212
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 any way to do this? (I tried #define Name1 Name2 and it didn't compile)
7
3438
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. However, I can declare concrete std::vectors as local variables in functions. Therefore, I would like to know whether the following construct is safe, i.e., there is no memory leak or undefined behavior. The demonstration example doesn't need...
5
1616
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 (0,1,1,2) and 2nd * vecotr has elements (0,1,1,2,3,5,8) then programme should say "TRUE" and if 2nd * vector is smaller then too it should say "TRUE", else it should say "FALSE". * */
8
14700
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 include all of it- it's over 1k lines long). In addition, I'm including an "include" file where structures like "stack" are defined. Again, it's really long. I doubt the problem lies there, though, because the include file is used in many other...
3
2115
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 better to use some other data structure if speed is critical i.e. maybe a struct like this- template <typename T> struct max_four { int element_count;
0
9589
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
10211
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
9994
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9863
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
7408
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6673
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5298
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
3958
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
3561
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

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.