Making a std::string a member of a union ???

P

Peter Olcott

Jim Langston said:
Jim Langston said:
Peter Olcott wrote:
Peter Olcott wrote:

If all that I want is std::string could I simply use [ std::string*
String ] in my union?
You would need management code to allocate and deallocate it.

I already figured that, are there any other issues?
You need to remember which element you stored in the vector.

Once you do all that you probably have reimplemented boost::any.

Okay then this is the way that I will do it.

It depends on what you are actually tryign to do. A union of a double and a
pointer doesn't seem like it will do you any good. It sounds more like you
want to refer to this double as either a double, or as a std::string,
correct? It would seem a simple class would work for you. Something like:

#include <iostream>
#include <string>
#include <sstream>

class AnyType
{
public:
operator double() const { return Val_; }
operator std::string () const
{
std::stringstream Convert;
Convert << Val_;
return Convert.str();
}
AnyType* operator= ( const double Val ) { Val_ = Val; return this; }
AnyType* operator= ( const std::string& Val )
{
std::stringstream Convert;
Convert << Val;
Convert >> Val_;
return this;
}
private:
double Val_;
};

int main()
{
AnyType MyDouble;
MyDouble = 1234.56;
std::cout << MyDouble << "\n";
MyDouble = "2345.67";
std::cout << MyDouble << "\n";

std::string wait;
std::getline( std::cin, wait );
}

This could easily be converted to a template for any type.

Is this the kind of thing you are looking for?

Peter Olcott said:
I can't tell what you are trying to do here, but, the std::string will
probably not hold data that can be converted to and from string.

Please don't top post. Message rearranged.

You mean not hold data that can be converted to and from a double?

Okay, so you want your union to hold *either* a std::string or a double. There
are a few ways to do this including templates, templates with common base
class, pointers, etc...

How is it you want to be able to use AnyType?
Its like I am making my own VARIANT record. I need some features that VARIANT
does not have.
 
S

Simon G Best

Peter said:
I don't think that it is a good fit for runtime polymorphism because I will have
datatypes with disjoint sets of operations, such as std::string and double.
runtime polymorphism is the best fit when the sets of operations are identical,
yet their specific implementation varies. This is not one of those cases.

The sets of operations don't have to be identical for runtime
polymorphism to be appropriate. And, as you seem to be finding, unions
don't seem to be suitable for your needs, either.

Why do you need or want to use a union? What problem is the union
supposed to solve? Is it that you want to store your "various elemental
data types" in the same container as if they're all of the same type
when they're not? Is it because they're all "elemental data types"
while, at the same time, they're various, different "elemental data
types"? If so, then runtime polymorphism is most probably exactly what
you need, as that's what polymorphism is very much about - it's pretty
much what the word 'polymorphism' means!
 
S

Simon G Best

Peter said:
>
Its like I am making my own VARIANT record. I need some features that VARIANT
does not have.

Is that "VARIANT record" in the Pascal sense? If it is, then I really
do think you probably want runtime polymorphism, as that is the C++ way
of doing that kind of thing.
 
P

Peter Olcott

Simon G Best said:
The sets of operations don't have to be identical for runtime polymorphism to
be appropriate. And, as you seem to be finding, unions don't seem to be
suitable for your needs, either.

Why do you need or want to use a union? What problem is the union supposed to
solve? Is it that you want to store your "various elemental data types" in
the same container as if they're all of the same type when they're not? Is it
because they're all "elemental data types" while, at the same time, they're
various, different "elemental data types"? If so, then runtime polymorphism
is most probably exactly what you need, as that's what polymorphism is very
much about - it's pretty much what the word 'polymorphism' means!

I am creating my own custom computer language interpreter. The language itself
is based on "C" and will interface with C++ native code.
 
P

Peter Olcott

Simon G Best said:
Is that "VARIANT record" in the Pascal sense? If it is, then I really do
think you probably want runtime polymorphism, as that is the C++ way of doing
that kind of thing.

One reason that I can't use run-time polymorphism is that the interpreted
language that I am constructing can not directly interface with polymorphic
class members. It will only have the capabilities of "C" and not C++.
 
S

Simon G Best

Peter said:
....

I am creating my own custom computer language interpreter. The language itself
is based on "C" and will interface with C++ native code.

That's far too vague and general. What's the /specific/ problem that
the union is supposed to solve? What is it /specifically/ that you're
trying to do?
 
P

Peter Olcott

Simon G Best said:
That's far too vague and general. What's the /specific/ problem that the
union is supposed to solve? What is it /specifically/ that you're trying to
do?

I have a single set of memory locations that must be able to store data of a
fixed set of types. A language lacking the capability of C++ must interface with
this data. The data types must include all of the elemental types {char, int,
double} and one string type based on wide characters and something like a string
build from a std::vector of struct.
 
S

Simon G Best

Peter said:
I have a single set of memory locations that must be able to store data of a
fixed set of types. A language lacking the capability of C++ must interface with
this data. The data types must include all of the elemental types {char, int,
double} and one string type based on wide characters and something like a string
build from a std::vector of struct.

That's still too vague.

* What do you mean by "a single set of memory locations"? Is that from
the perspective of your interpreted language?

* When you say, "A language lacking the capability of C++ must
interface with this data", what do you mean by "interface"?

If you're trying to do what I /think/ you're trying to do, then I think
you're probably failing to properly separate your interpreted language
from your implementation of its interpreter. But as you're not at all
clear on what you're actually trying to do, I can only guess.
 
P

Peter Olcott

Simon G Best said:
That's still too vague.

* What do you mean by "a single set of memory locations"? Is that from the
perspective of your interpreted language?

It will be implemented as a std::vector said:
* When you say, "A language lacking the capability of C++ must interface with
this data", what do you mean by "interface"?

Read and write based on subscript.
If you're trying to do what I /think/ you're trying to do, then I think you're
probably failing to properly separate your interpreted language from your
implementation of its interpreter. But as you're not at all

I have no choice in this, the interpreted language is provided by a third party.
I am hooking this third party interpreted language into my system and then
exposing another different interpreted language implemented in terms of the
third party language.
 
J

Jim Langston

Peter Olcott said:
One reason that I can't use run-time polymorphism is that the interpreted
language that I am constructing can not directly interface with
polymorphic class members. It will only have the capabilities of "C" and
not C++.

Okay, I think the easiest way would be to have a class that can store any of
the possible types of data. You'll need to overload operator= and operator
type for each type, then you'll want to store in this class what type is
actually being used. You'll have problems, however, when the type is
arbitary.

class AnyType
{
public:
operator std::string() { return StringVal; }
operator int() { return IntVal; }
// etc...
};

int main();
{
AnyType Foo;
// yada yada

std::cout << AnyType << "\n";
// ooops, what type is it supposed to output? std::string? int? float?
double? char? etc..
}

Assignments and constructors would be easier, because there will be a parm
that says what type it is.

AnyType Foo;
Foo = 12;
12 is an integer, and so would use operator=( const int ); no ambiguity
there.

AnyType Foo( 12.5 );
12.5 is a double, and so would use the constructor accepting double, so no
ambiguity there.

You will have problems when the type isn't known because of no parameter.
What is accepted in it's use?

std::cout << AnyType.val(INT) << "\n";
is something like that acceptable?
 
S

Simon G Best

Peter said:
It will be implemented as a std::vector<AnyType> Any;

Doesn't really answer the question I asked. I was asking about /what it
is/ you're implementing, not /how you're implementing/ it.
Read and write based on subscript.

Which doesn't tell me whether that's /in the language/ you're
implementing, or /in the implementation/ of your language, or whatever.

But what I do gather is that you want an array-like container of things
(the std::vector<AnyType>), where those things are all "elemental" types
of data, but are various, different "elemental" types of data. It still
sounds very much like runtime polymorphism.
I have no choice in this, the interpreted language is provided by a third party.
I am hooking this third party interpreted language into my system and then
exposing another different interpreted language implemented in terms of the
third party language.

Oh, /two/ interpreted languages.

Well, you still haven't really said why runtime polymorphism wouldn't
work. And, as you're still not being at all clear on this stuff, on
what you're actually trying to do, I'm giving up.
 
P

Peter Olcott

Simon G Best said:
Doesn't really answer the question I asked. I was asking about /what it is/
you're implementing, not /how you're implementing/ it.


Which doesn't tell me whether that's /in the language/ you're implementing, or
/in the implementation/ of your language, or whatever.

But what I do gather is that you want an array-like container of things (the
std::vector<AnyType>), where those things are all "elemental" types of data,
but are various, different "elemental" types of data. It still sounds very
much like runtime polymorphism.


Oh, /two/ interpreted languages.

Well, you still haven't really said why runtime polymorphism wouldn't work.
And, as you're still not being at all clear on this stuff, on what you're
actually trying to do, I'm giving up.

I did say why run-time polymorphism wouldn't work and you did not pay attention
to this answer. Maybe I should have been more specific. Runtime polymorphism
will not work because a language that is incapable of accessing polymorphic
functions must have direct access to the underlying data. The language can not
even call polymorphic functions. For all practical purposes this language is
"C". What can "C" do with polymorphism?
 
P

Peter Olcott

Jim Langston said:
Okay, I think the easiest way would be to have a class that can store any of
the possible types of data. You'll need to overload operator= and operator
type for each type, then you'll want to store in this class what type is
actually being used. You'll have problems, however, when the type is
arbitary.

class AnyType
{
public:
operator std::string() { return StringVal; }
operator int() { return IntVal; }
// etc...
};

I need more details to see how this would work. What does the private data look
like?
 
S

Simon G Best

Peter said:
I did say why run-time polymorphism wouldn't work and you did not pay attention
to this answer. Maybe I should have been more specific. Runtime polymorphism
will not work because a language that is incapable of accessing polymorphic
functions must have direct access to the underlying data. The language can not
even call polymorphic functions. For all practical purposes this language is
"C". What can "C" do with polymorphism?

This just seems wrong and confused. It's certainly very unclear.
You're not clear on /which/ of the two interpreted languages needs to
directly access the data. You haven't said /why/ stuff in the
interpreted language would need such direct access. You haven't been at
all clear on what the actual, specific problem is that the union is
supposed to solve. It's because of this persistent lack of clarity that
I'm giving up.
 
P

Peter Olcott

Simon G Best said:
This just seems wrong and confused. It's certainly very unclear.

How can providing a "C" interface to C++ data possibly be either wrong of
confused?
You're not clear on /which/ of the two interpreted languages needs to directly
access the data. You haven't said /why/ stuff in the

I did not say that there are two interpreted languages. There are two different
abstractions of the same interpreted language. For all practical purposes these
details can be abstracted out of the problem. For all practical purposes the
problem is simply providing "C" access to C++ data.

It can often be quite annoying when people insist on having me provide all of
the irrelevant details before they are willing to answer the question, and they
then still refuse to answer the question because they have become confused by
all the irrelevant details.

I wish that people would stop trying to second guess my questions, and just
answer them.
 
J

Jim Langston

Peter Olcott said:
I need more details to see how this would work. What does the private data
look like?

I was doing a sample, and this is class is anything but trivial. With
templates it would become a lot more trivial. With polymorphism, it would
become a lot more trivial. Without either tool it's a lot of coding. A
seperate constructor for each type. A seperate operator= for each type. A
seperate operator type for each type. At least one operator+ for each type,
probably more (AnyType int + AnyType int. AnyType int + AnyType short.
AnyType int + int, etc...)

I think if you want a variant class you should find the source code for one
(gcc provides source) and modify it to do the things you need it to do,
otherwise you'll spend a long time reinventing the wheel.
 
J

Jim Langston

Peter Olcott said:
How can providing a "C" interface to C++ data possibly be either wrong of
confused?


I did not say that there are two interpreted languages. There are two
different abstractions of the same interpreted language. For all practical
purposes these details can be abstracted out of the problem. For all
practical purposes the problem is simply providing "C" access to C++ data.

It can often be quite annoying when people insist on having me provide all
of the irrelevant details before they are willing to answer the question,
and they then still refuse to answer the question because they have become
confused by all the irrelevant details.

I wish that people would stop trying to second guess my questions, and
just answer them.

Sorry, it doesn't work this way. If you've paid any attention to this group
for any length of time (or all the C++ groups I've seen so far) for any non
trivial algorithm question (which this actually is) the use for which it's
going to be put usually has to be known, because different uses make
different algorithms.

A lot of the time the reason is simply because the person is asking, they
don't understand that maybe there's something already in the C++ language
that will do it for them. An example being, someone asks about making
pointers to nodes. Someone asks them for what, they say so they can make a
linked list. Well, have you tried std::list? Oh, didn't know that existed
(I've seen this actual exchange).

Another good reason is becuase the person asking for a clarification can
think of more than one way to solve the problem, but they don't know which
solution would fit the answer, so they ask for clarifcation.

Your original question is a good case in point, you were asking if a
std::string can be a member of a union, and it turns out that, no, it can't
be the way you want it to. But people asked what you needed it for which
brought on this thread of the thread.

If you don't want anyone to ask you any more questions, fine. Your answer
is no, you can't make a std::string part of a union. Thread over.
 
P

Peter Olcott

Jim Langston said:
I was doing a sample, and this is class is anything but trivial. With
templates it would become a lot more trivial. With polymorphism, it would
become a lot more trivial. Without either tool it's a lot of coding. A
seperate constructor for each type. A seperate operator= for each type. A
seperate operator type for each type. At least one operator+ for each type,
probably more (AnyType int + AnyType int. AnyType int + AnyType short.
AnyType int + int, etc...)

I could already infer those details. The detail that I am missing is how the
data itself is declared.

union AnyType {
std::string String;
int Integer;
};

Will not compile. The best that I could figure so far is this:

union AnyType {
std::string* String;
int Integer;
};
 
P

Peter Olcott

Jim Langston said:
Sorry, it doesn't work this way. If you've paid any attention to this group
for any length of time (or all the C++ groups I've seen so far) for any non
trivial algorithm question (which this actually is) the use for which it's
going to be put usually has to be known, because different uses make different
algorithms.

A lot of the time the reason is simply because the person is asking, they
don't understand that maybe there's something already in the C++ language that
will do it for them. An example being, someone asks about making pointers to
nodes. Someone asks them for what, they say so they can make a linked list.
Well, have you tried std::list? Oh, didn't know that existed (I've seen this
actual exchange).

Another good reason is becuase the person asking for a clarification can think
of more than one way to solve the problem, but they don't know which solution
would fit the answer, so they ask for clarifcation.

Your original question is a good case in point, you were asking if a
std::string can be a member of a union, and it turns out that, no, it can't be
the way you want it to. But people asked what you needed it for which brought
on this thread of the thread.

If you don't want anyone to ask you any more questions, fine. Your answer is
no, you can't make a std::string part of a union. Thread over.

So the next best thing is a union including std::string*
 
M

Michael DOUBEZ

Peter Olcott a écrit :
So the next best thing is a union including std::string*
Or a struct with a union of unionable types:
struct MyAny
{
std::string str;
union
{
long int num;
float big;
double huge;
...
} tohubohu;
};

This cost only a string object and doesn't require dynamic allocation,
overload of copy operator ...

If you can afford it.
 

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

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top