Note that there are some explanatory texts on larger screens.

plurals
  1. PORewritable dynamically-typed value as a class member
    primarykey
    data
    text
    <p>(This is sort of a long-winded question but I have summarized it at the bottom.)</p> <p>I want to write a class (in C++) that performs tests on objects of some unknown type deriving from a very skeletal base class. The idea is that an object of this class is initialized with an "expected" result and then called many times, saving the outcome and comparing it to the expected one. The whole package should look something like this:</p> <pre><code>struct test_input { virtual ~test_input() = 0; }; struct test_output { virtual bool operator== (const test_output&amp;) = 0; virtual ~test_output() = 0; }; typedef test_output&amp; (*test_function)(test_input&amp;); class test { const test_input &amp;data; const test_output &amp;expected; test_output *result; test(test_input &amp;i, test_output &amp;o) : data(i), expected(o), result(NULL) {} bool operator() (test_function &amp;trial) { return *(result = &amp;trial(data)) == expected; } }; // Example usage class ti_derived : public test_input { /* ... */ }; class to_derived : public test_output { /* ... */ }; to_derived&amp; some_function_one(ti_derived &amp;arg) { /* ... */ } to_derived&amp; some_function_two(ti_derived &amp;arg) { /* ... */ } ti_derived ti; // Somehow initialized to_derived correct; // Somehow determined test test_object(ti, correct); if (!test_object(&amp;some_function_one)) { cout &lt;&lt; "1: " &lt;&lt; test_object.result; } if (!test_object(&amp;some_function_two)) { cout &lt;&lt; "2: " &lt;&lt; test_object.result; } </code></pre> <p>My intention is that the same object of type <code>test</code> can be called repeatedly on many <code>test_function</code>s, which is why its member <code>result</code> must be a pointer rather than a reference: I can't reassign a reference.</p> <p>The problem is that the code for <code>operator()</code> is wrong: the left-hand side is not a reference to a <code>test_output</code>, so it is statically cast to the exact class <code>test_output</code>, which is purely virtual; however, I want <code>operator==</code> to be dynamically bound to the equality operator for type <code>to_derived</code>. As is, it will try to downgrade <code>expected</code> to the base type <code>test_output</code> and complain that I don't have such an operator (and if I did, it would be the wrong one anyway). Note: switching the order of the operands would cause <code>operator==</code> to be that of <code>to_derived</code>, but then the compiler would complain that the type of the second argument was wrong.</p> <p>I guess I could make <code>test</code> a template depending on types, say <code>template &lt;typename I, typename O&gt;</code>, replacing <code>test_input</code> and <code>test_output</code> in its code, but that is not so good because it fails to specify that <code>I</code> and <code>O</code> inherit the virtual functions I want (which is why I have those two classes in the first place).</p> <p>It's tempting, though sort of inelegant, to want to overload <code>operator==</code> on type <code>test_output*</code>, but that's not legal, is it? I could make only one of the arguments a pointer, since <code>expected</code> can remain a reference type, but again: inelegant. This is not how I would write the code if I did not need <code>result</code> to be reassignable, and so it is not how I want to write the code.</p> <p>If this were not in a class, I could just define a new reference variable every time I want to save a new <code>result</code>, but I can only have so many members. Syntactically, this sounds like a situation where I'd want a "pointer to a reference to <code>test_output</code>", but that's illegal also. (Either that, or something like a "<code>rebind</code>" operator for references.) A <code>test_output **</code> is no good, since I want to ultimately be able to pass objects of (base) type <code>test_output</code>; if I do one dereference I just get a <code>test_output *</code>, but if I do two then the type is no longer dynamic.</p> <p>So how do I do this? Specifically, I want:</p> <ul> <li><p>to bind the equivalent of <code>operator==(*result, expected)</code> to the equality operator for the dynamic types of these things;</p></li> <li><p>to be able to indicate to the compiler that those types are derived from <code>test_output</code>;</p></li> <li><p>to be able to reassign <code>result</code>.</p></li> </ul> <p>I am also wondering: in my sample usage, is it valid to use those function pointers as arguments to <code>test_object</code>? Their arguments can be dynamically typed but I don't know whether that means the function type itself has an automatic conversion to the function type taking and returning the respective base types. If not, how would I indicate a function of this dynamically-typed signature?</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.
 

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