Re: Abstract base class requires a virtual template: fixes?
On 27 Jun, 12:16, Dom Jackson <nos...@mci2000.com> wrote:
Hello -
I have a problem where I need to test some numeric code using a
variety of built-in integer types:
obj_type1 = obj_type2 OP obj_type3; // is obj_type1 correct?
If I test with 10 built-in integer types, then I get 1000 permutations
of the above statement. If I then test a dozen different operators, I
get over 10,000 test operations.
Obviously, I need some generic way to handle this. I can't immediately
see a static/template-based solution, but it seems like I should be
able to do this dynamically. My first pass at a solution looks like:
1 - define an 'integer object' abstract base class, IntObject
2 - define a virtual templated method 'get()' in IntObject, which
returns a pointer to an object of a templated integer type
3 - define a derived class for each integer type of interest; this
stores an object of that type, and defines the virtual 'get()'
function to return a pointer to this object
4 - my test code can now declare an array of IntObject pointers, and
can randomly select a pointer in this array. Calling the 'get()'
method then returns an object pointer of an effectively random type
for testing:
IntObject* res_array, opL_array, opR_array;
...
res_index = rand() % 10;
opL_index = rand() % 10;
opR_index = rand() % 10;
*(res_array[res_index]->get()) =
*(opL_array[opL_index]->get()) OP *(opR_array[opR_index]->get());
The problem is, this doesn't work, because C++ doesn't allow templated
virtuals:
also, there is no way for a compiler to deduce T from call to get().
class IntObject {
public:
template<typename T>
virtual T* get(void) const = 0; // ERROR
};
Any ideas on how I can get around this problem, or any better
solutions?
not as easy as you've tried. look up some sort of variant
like boost::variant
say you have int and long integer types to work with
typedef boost::variant<int, long> my_integer;
provide visitor for each operation and each
type combination (sorry).
struct plus_visitor : public boost::static_visitor<my_integer>
{
my_integer operator()(int i, int j) const
{
return my_integer(i+j);
}
my_integer operator()(long i, long j) const
{
return my_integer(i+j);
}
my_integer operator()(int i, long j) const
{
return my_integer((long)i+j);
}
my_integer operator()(long i, int j) const
{
return my_integer(i+(long)j);
}
};
it also works for template operators if you can
treat types generically
struct reveal : public boost::static_visitor<void>
{
template<class T>
void operator()(T const & t) const
{
std::cout << t <<'\n';
}
};
int main()
{
my_integer i(1); // hold int
my_integer j(1L); // holds long
// k = i + j;
my_integer k = ::boost::apply_visitor(plus_visitor(), i, j);
::boost::apply_visitor(reveal(), k);
}
That is the best I can think of.
Many thanks -
Dom
regards
DS