Note that there are some explanatory texts on larger screens.

plurals
  1. POInterfaces and covariance problem
    primarykey
    data
    text
    <p>I have a particular class that stores a piece of data, which implements an interface:</p> <pre><code>template&lt;typename T&gt; class MyContainer : public Container&lt;T&gt; { class Something : public IInterface { public: // implement *, -&gt;, and ++ here but how? private: T x; }; // implement begin and end here, but how? private: Something* data; // data holds the array of Somethings so that references to them can be returned from begin() and end() to items in this array so the interface will work, but this makes the problem described below }; </code></pre> <p>And I have an array of <code>Something</code>s.</p> <p>I have the need for <code>Something</code> to implement an interface class (<code>IInterface</code> in the example) which:</p> <ol> <li>Contains pure virtual member functions which return something such that <code>*retval</code> returns a reference to the <code>x</code> member, <code>retval-&gt;</code> returns the address of <code>x</code>, and <code>++retval</code> makes <code>retval</code> refer to the next <code>Something</code> in the array.</li> <li>The things that the pure virtual members return can be inherited from and returned by the implementation of the members</li> <li><code>container[i]</code> (where <code>container</code> is the array holding the <code>Something</code> objects) always returns something such that <code>*retval</code> always returns a reference to the same <code>T</code> for the same <code>i</code>.</li> </ol> <p>Right now, the interface looks like this:</p> <pre><code>template&lt;typename T&gt; class Container { class IInterface { public: virtual T&amp; operator*() = 0; virtual T* operator-&gt;() = 0; virtual IInterface&amp; operator++(); // this is the problem }; // returning a reference right now to support covariance, so subclasses can // derive from Container and then have a member class derive from IInterface // and override these to return their derived class, but this has a problem virtual IInterface&amp; begin() = 0; virtual IInterface&amp; end() = 0; }; </code></pre> <p>My current solution (have the virtual methods return an <code>IInterface&amp;</code> and return a <code>Something&amp;</code> in the implementation) has no problem with the requirements, <strong>except</strong> for the <code>++retval</code> requirement. Because the <code>Something</code> is directly tied to the object it holds and can't point to a <code>T</code> with a pointer, there's no way that I can find to get <code>++</code> to make the variable refer to the next <code>Something</code> in the array.</p> <p>If it helps to know, this is an iterator type system. I would have made it with the STL style iterators (where you just have an array of <code>T</code>) that are passed around by value and hold pointers to the values they represent, but that would break the interface because only references and pointers are covariant, and the objects already have to exist somewhere else already (in my code they're in the array) so you don't return a reference to a local object.</p> <p>The purpose of this setup is so that one can write functions that take a <code>Container&amp;</code> and iterate the container without knowing what type of container it is:</p> <pre><code>void iterate(Container&lt;int&gt;&amp; somecontainer) { Container&lt;int&gt;::IIterator i = somecontainer.begin(); // right now this would return a reference, but it doesn't/can't work that way while (i != somecontainer.end()) { doSomething(*i); ++i; // this is the problem } } </code></pre> <p>It's kind of difficult for me to describe, don't hesitate to let me know if you need more information.</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.
 

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