Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

a linked list with element different types in C++

80 views
Skip to first unread message

asetof...@gmail.com

unread,
Oct 3, 2017, 2:56:39 PM10/3/17
to
Is it possible write a double linked list, with type not the same?

Example
[1, "this", 1.23, [1,2,3], []]

asetof...@gmail.com

unread,
Oct 3, 2017, 2:59:54 PM10/3/17
to
I have as the impression that the only implementation possible it is a double linked list where the node has a char*, pointed where store the different type element...

Chris Vine

unread,
Oct 3, 2017, 3:04:39 PM10/3/17
to
With C++17 you can use std::variant. Otherwise you are probably going
to have to implement your own hack with unions or using pointers with
run-time type introspection.

Jerry Stuckle

unread,
Oct 3, 2017, 3:24:00 PM10/3/17
to
Or create different classes derived from the same base class.

--
==================
Remove the "x" from my email address
Jerry Stuckle
jstu...@attglobal.net
==================

Öö Tiib

unread,
Oct 3, 2017, 4:59:43 PM10/3/17
to
With C++98 the linked lists were as rarely useful as these are
now. If one needed variant in C++ then it was usually better to
use some variant from library (like for example boost::variant or
QVariant) instead of hacking unions.

Chris Vine

unread,
Oct 3, 2017, 5:23:46 PM10/3/17
to
On Tue, 3 Oct 2017 15:23:48 -0400
Jerry Stuckle <jstu...@attglobal.net> wrote:
> On 10/3/2017 3:04 PM, Chris Vine wrote:
> > On Tue, 3 Oct 2017 11:56:31 -0700 (PDT)
> > asetof...@gmail.com wrote:
> >> Is it possible write a double linked list, with type not the same?
> >>
> >> Example
> >> [1, "this", 1.23, [1,2,3], []]
> >
> > With C++17 you can use std::variant. Otherwise you are probably
> > going to have to implement your own hack with unions or using
> > pointers with run-time type introspection.
> >
>
> Or create different classes derived from the same base class.

That would do it, although I guess that counts as "pointers with
run-time type introspection" (you have to hold the base type by
reference/pointer to avoid slicing). I try to avoid inheritance where
it doesn't directly model the problem space: but I make an exception
for type erasure, and you are right that it is probably the most
reasonable approach if unions are not suitable and a variant type is
not available.

Jerry Stuckle

unread,
Oct 3, 2017, 10:10:58 PM10/3/17
to
I agree I don't like to use inheritance in cases like this where there
is not a direct relationship in the model. But nothing's perfect,
either. And even if you use unions you need to keep some type of
indicator as to what member(s) is being used. Not a good answer, either.

But the real question here is - why would one need a collection of such
disparate types? I think that's where the problem lies, and also the
real answer to the problem. I think this is a case of poor design.

Ian Collins

unread,
Oct 3, 2017, 11:48:29 PM10/3/17
to
Representing JSON objects or something similar.

--
Ian

David Brown

unread,
Oct 4, 2017, 2:49:59 AM10/4/17
to
std::list<std::any> ? I have never used it myself.

asetof...@gmail.com

unread,
Oct 4, 2017, 3:35:20 AM10/4/17
to
In Axiom (cas system) a generic List of type generic has type "List Any"

Chris Vine

unread,
Oct 4, 2017, 7:59:34 AM10/4/17
to
Lists in C++ are generic. They are also homogeneous.

Different languages make different choices. Dynamically typed
languages tend to have heterogeneous containers (lisp, scheme, python);
statically typed languages tend to have homogeneous containers, so you
have to use a variant type to mix types in the container (C++, Ocaml,
Haskell).

So far as C++ is concerned this follows the principle that you don't
pay for what you don't use. Homogeneous containers such as vectors can
be implemented in contiguous memory; heterogeneous containers require
addition indirection.

Jerry Stuckle

unread,
Oct 4, 2017, 9:46:03 AM10/4/17
to
And why would that be necessary? JSON is a means of communicating
objects, i.e. between systems or in files. Every time I've used JSON
objects the first thing I've done in getting one is create a real object
out of it - and do whatever is appropriate for that object.

Cholo Lennon

unread,
Oct 4, 2017, 12:36:12 PM10/4/17
to
+1

IMHO, a list of any (std::any or boost::any) is the way to go in this
particular case (unless the OP adds more information to consider using a
list of variant)

Regards

--
Cholo Lennon
Bs.As.
ARG


Richard

unread,
Oct 4, 2017, 2:48:37 PM10/4/17
to
[Please do not mail me a copy of your followup]

Ian Collins <ian-...@hotmail.com> spake the secret code
<f3j402...@mid.individual.net> thusly:
JSON isn't open-ended though, a value is either null, bool, number,
string, array of value or dictionary of value (map of string -> value).
So while they are "different types" it's easily handled with a
suitable recursive variant. It's things like Java's "list of Object"
that aren't easily done in C++ because Java/C# have that idea that
every reference type derives from Object.
--
"The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline>
The Terminals Wiki <http://terminals-wiki.org>
The Computer Graphics Museum <http://computergraphicsmuseum.org>
Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com>

Ian Collins

unread,
Oct 4, 2017, 3:10:12 PM10/4/17
to
On 10/ 5/17 07:48 AM, Richard wrote:
> [Please do not mail me a copy of your followup]
>
> Ian Collins <ian-...@hotmail.com> spake the secret code
> <f3j402...@mid.individual.net> thusly:
>
>> On 10/ 4/17 03:10 PM, Jerry Stuckle wrote:
>>> But the real question here is - why would one need a collection of such
>>> disparate types? I think that's where the problem lies, and also the
>>> real answer to the problem. I think this is a case of poor design.
>>
>> Representing JSON objects or something similar.
>
> JSON isn't open-ended though, a value is either null, bool, number,
> string, array of value or dictionary of value (map of string -> value).
> So while they are "different types" it's easily handled with a
> suitable recursive variant.

It's those types that were in the the OP's original list! No matter how
you represent it, it is still a collection of disparate types.

--
Ian

Richard

unread,
Oct 4, 2017, 3:38:08 PM10/4/17
to
[Please do not mail me a copy of your followup]

Ian Collins <ian-...@hotmail.com> spake the secret code
<f3kq08...@mid.individual.net> thusly:
Disparate types where you know all the types of what it could be in
advance, so std::variant should be able to do the job.

Ian Collins

unread,
Oct 4, 2017, 5:01:45 PM10/4/17
to
On 10/ 5/17 08:37 AM, Richard wrote:
> [Please do not mail me a copy of your followup]
>
> Ian Collins <ian-...@hotmail.com> spake the secret code
> <f3kq08...@mid.individual.net> thusly:
>
>> On 10/ 5/17 07:48 AM, Richard wrote:
>>> JSON isn't open-ended though, a value is either null, bool, number,
>>> string, array of value or dictionary of value (map of string -> value).
>>> So while they are "different types" it's easily handled with a
>>> suitable recursive variant.
>>
>> It's those types that were in the the OP's original list! No matter how
>> you represent it, it is still a collection of disparate types.
>
> Disparate types where you know all the types of what it could be in
> advance, so std::variant should be able to do the job.

Quite. My own JSON library uses a variant like object with constructors
from and conversions to the set of types used by JSON. The acceptable
types are specified as

std::tuple<int64_t,bool,double,Null,std::string,Object,Array>;

My original answer still stands: JSON objects are a valid use case for a
collection of disparate (all be it known) types.

--
Ian

Jorgen Grahn

unread,
Oct 5, 2017, 3:02:31 PM10/5/17
to
On Wed, 2017-10-04, Jerry Stuckle wrote:
> On 10/3/2017 11:48 PM, Ian Collins wrote:
>> On 10/ 4/17 03:10 PM, Jerry Stuckle wrote:
...
>>> But the real question here is - why would one need a collection of such
>>> disparate types?  I think that's where the problem lies, and also the
>>> real answer to the problem.  I think this is a case of poor design.
>>
>> Representing JSON objects or something similar.
>
> And why would that be necessary?

(He didn't say it was necessary.)

> JSON is a means of communicating
> objects, i.e. between systems or in files. Every time I've used JSON
> objects the first thing I've done in getting one is create a real object
> out of it - and do whatever is appropriate for that object.

I tend to do the same. There's already the external representation
(JSON) and the internal one (the data structures my code does concrete
work with); I don't want a third one, especially if it's more
open-ended than the other two.

I guess design bias like that is the reason I've never used variant/any/etc.

/Jorgen

--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .

Jerry Stuckle

unread,
Oct 5, 2017, 5:35:12 PM10/5/17
to
On 10/5/2017 3:02 PM, Jorgen Grahn wrote:
> On Wed, 2017-10-04, Jerry Stuckle wrote:
>> On 10/3/2017 11:48 PM, Ian Collins wrote:
>>> On 10/ 4/17 03:10 PM, Jerry Stuckle wrote:
> ...
>>>> But the real question here is - why would one need a collection of such
>>>> disparate types?  I think that's where the problem lies, and also the
>>>> real answer to the problem.  I think this is a case of poor design.
>>>
>>> Representing JSON objects or something similar.
>>
>> And why would that be necessary?
>
> (He didn't say it was necessary.)
>

Then why bring it up?

>> JSON is a means of communicating
>> objects, i.e. between systems or in files. Every time I've used JSON
>> objects the first thing I've done in getting one is create a real object
>> out of it - and do whatever is appropriate for that object.
>
> I tend to do the same. There's already the external representation
> (JSON) and the internal one (the data structures my code does concrete
> work with); I don't want a third one, especially if it's more
> open-ended than the other two.
>
> I guess design bias like that is the reason I've never used variant/any/etc.
>
> /Jorgen
>

For me it's not bias. I've just never found a need for it - there have
always been better ways.

Ian Collins

unread,
Oct 6, 2017, 3:15:49 AM10/6/17
to
On 10/ 6/17 08:02 AM, Jorgen Grahn wrote:
> On Wed, 2017-10-04, Jerry Stuckle wrote:
>> On 10/3/2017 11:48 PM, Ian Collins wrote:
>>> On 10/ 4/17 03:10 PM, Jerry Stuckle wrote:
> ....
>>>> But the real question here is - why would one need a collection of such
>>>> disparate types? I think that's where the problem lies, and also the
>>>> real answer to the problem. I think this is a case of poor design.
>>>
>>> Representing JSON objects or something similar.
>>
>> And why would that be necessary?
>
> (He didn't say it was necessary.)
>
>> JSON is a means of communicating
>> objects, i.e. between systems or in files. Every time I've used JSON
>> objects the first thing I've done in getting one is create a real object
>> out of it - and do whatever is appropriate for that object.
>
> I tend to do the same. There's already the external representation
> (JSON) and the internal one (the data structures my code does concrete
> work with); I don't want a third one, especially if it's more
> open-ended than the other two.
>
> I guess design bias like that is the reason I've never used variant/any/etc.

For the infrastructure support applications I'm frequently called upon
to write, JSON is a good internal and external format to use. These
applications tend to follow a pattern along the lines of get tree like
data from A, manipulate it and merge it with B or compare tree like data
from A and B and update one to match the other. It's easier just to use
JSON to transfer the data and manipulate it without needing to know the
types involved.

Once you have a set of algorithms (along the lines of the standard
container algorithms) to manipulate JSON objects, you can reuse them for
processing pretty much anything.

--
Ian

Juha Nieminen

unread,
Oct 6, 2017, 4:12:51 AM10/6/17
to
Cholo Lennon <cholo...@hotmail.com> wrote:
> On 04/10/17 03:49, David Brown wrote:
>> std::list<std::any> ? I have never used it myself.
>
> IMHO, a list of any (std::any or boost::any) is the way to go in this
> particular case (unless the OP adds more information to consider using a
> list of variant)

The traditional object-oriented way is to have a

std::list<std::unique_ptr<SomeBaseClass>>

and then creating all the types you want to be able to add there
as derived classes of that SomeBaseClass.

This may be a bit more cumbersome in C++ because if you want to
store, for example, an int, you'll have to create your own class,
derived from SomeBaseClass, that behaves like an int.

Richard

unread,
Oct 6, 2017, 1:32:04 PM10/6/17
to
[Please do not mail me a copy of your followup]

Ian Collins <ian-...@hotmail.com> spake the secret code
<f3oosr...@mid.individual.net> thusly:

>Once you have a set of algorithms (along the lines of the standard
>container algorithms) to manipulate JSON objects, you can reuse them for
>processing pretty much anything.

Indeed. I do find myself using nodejs for this sort of fiddling.
Works great for things that aren't performance sensitive. Even so, I
wouldn't discount the throughput you can get through nodejs because
all the IO is asynchronous. I wrote a dashboard for a team I worked
on that scrubbed through all the source code looking for TODO comments
and such and it was much faster than I expected. That might have
changed if I had all the source code on a fast SSD instead of spinning
rust, though :).

Cholo Lennon

unread,
Oct 6, 2017, 4:55:31 PM10/6/17
to
I agree with you, that's why (in C++) I tend to use a list of any (or
variant). In other languages like Java or Python it's easy to have an
heterogenous collection due to a (default) common base class.
0 new messages