Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>There are many ways to solve the problem of data structures with varying members and which is best depends a lot on how exactly it is going to be used. </p> <p>The most obvious is to use inheritance. You derive all your possibilities from a base class:</p> <pre><code>struct base_struct { int id; std::string name; }; list&lt;base_struct*&gt; some_list; struct some_struct : public base_struct { double metricA; }; struct some_other_struct : public base_struct { int metricB; }; base_struct *s1 = new some_struct; s1-&gt;id = 1; // etc base_struct *s2 = new some__other_struct; s2-&gt;id = 2; // etc some_list.push_back(s1); some_list.push_back(s2); </code></pre> <p>The tricky bit is that you'll have to make sure that when you get elements back out, you case appropriately. <code>dynamic_cast</code> can do this in a type-safe manner:</p> <pre><code>some_struct* ss = dynamic_cast&lt;some_struct*&gt;(some_list.front()); </code></pre> <p>You can query the name before casting using <code>type_info</code>:</p> <pre><code>typeid(*some_list.front()).name(); </code></pre> <p>Note that both these require building with RTTI, which is usually OK, but not always as RTTI has a performance cost and can bloat your memory footprint, especially if templates are used extensively.</p> <p>In a previous project, we dealt with something similar using <a href="http://www.boost.org/doc/libs/1_49_0/doc/html/any.html" rel="nofollow">boost any</a>. The advantage of <code>any</code> is that it allows you to mix types that aren't derived from one another. In retrospect, I'm not sure I'd do that again because it made the code a bit too apt to fail at runtime because type checking is being deferred until then. (This is true of the <code>dynamic_cast</code> approach as well.</p> <p>In the bad old C days, we solved this same problem with a <code>union</code>:</p> <pre><code>struct base_struct { int id; std::string name; union { // metricA and metricB share memory and only one is ever valid double metricA; int metricB; }; }; </code></pre> <p>Again, you have the problem that you have to deal with ensuring that it is the right type yourself.</p> <p>In the era before the STL, many container systems were written to take a <code>void*</code>, again requiring the user to know when to cast. In theory, you could still do that by saying <code>list&lt;void*&gt;</code> but you'd have no way to query the type.</p> <p>Edit: Never, <em>ever</em> use the <code>void*</code> method!</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload