473,396 Members | 1,666 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

Abstract base class requires a virtual template: fixes?

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:

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?

Many thanks -

Dom
Jun 27 '07 #1
2 1869
On 27 Jun, 12:16, Dom Jackson <nos...@mci2000.comwrote:
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, longmy_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

Jun 27 '07 #2
Dom Jackson a écrit :
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. [snip]
Perhaps a typelist is what you need. Giving an example with addition:

//generic typelist system
template <typename T1, typename T2>
struct TypeList
{
typedef T1 Head;
typedef T2 Tail;
};
//end of list type
struct NullType {};

// define a list with your types
typedef TypeList<long, TypeList<int, TypeList<short, NullType IntList;

//implementation of the plus operation as recursive template
template < typename TList1 , typename TList2 , typename TListInistruct
plus_operation_imp;

//general case of recursion
template < typename T1, typename T2 , typename T3, typename T4 ,
typename TListIni>
struct plus_operation_imp< TypeList<T1, T2, TypeList<T3, T4,
TListIni :
public plus_operation_imp< TypeList<T1, T2, T4, TListIni>
{
T1 operator()(T1 lhs,T3 rhs)
{
return lhs+rhs;
}
};

//recursion at end of list for right hand side
template < typename T1, typename T2 , typename T3 , typename TListIni>
struct plus_operation_imp< TypeList<T1, T2, TypeList<T3, NullType>
,TListIni:
public plus_operation_imp< T2 , TListIni, TListIni>
{
T1 operator()(T1 lhs,T3 rhs)
{
return lhs+rhs;
}
};
//recursion at end of both list
template < typename T1, typename T3 , typename TListIni>
struct plus_operation_imp< TypeList<T1, NullType, TypeList<T3,
NullType, TListIni>
{
T1 operator()(T1 lhs,T3 rhs)
{
return lhs+rhs;
}
};

//type to initialize recursion
template<typename TList>
struct plus_operation: public plus_operation_imp<TList,TList,TList>
{};

//here is your functor
plus_operation<IntListmyoperation;

Then you can call myoperation with any combinaison of parameters.
myoperation(long,long);
myoperation(long,int);
myoperation(int,int);
myoperation(int,long);
....

You might even automatize that with MPL but I am not familiar enough
with it to tell you.

Michael
Jun 27 '07 #3

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
by: Jef Driesen | last post by:
Suppose I have an abstract base class that looks like this: template <typename T> class base { public: // Typedefs typedef double value_type; typedef std::size_t size_type; public: //...
4
by: WittyGuy | last post by:
Hi all, Though I know the concepts of both abstract class & virtual function (like derived class pointer pointing to base class...then calling the function with the pointer...), what is the real...
33
by: Chris Capel | last post by:
What is the rationale behind the decision not to allow abstract static class members? It doesn't seem like it's a logically contradictory concept, or that the implementation would be difficult or...
8
by: Asfand Yar Qazi | last post by:
Hi, I have the following header file in my 'everything useful I think of in one place' library: ============= BEGIN CODE SNIPPET =========== /** All classes that derive from this obtain a...
0
by: mailforpr | last post by:
Hi. Let me introduce an iterator to you, the so-called "Abstract Iterator" I developed the other day. I actually have no idea if there's another "Abstract Iterator" out there, as I have never...
6
by: Nindi | last post by:
5 Files Singleton.h The Singleton Factory.h The factory creating new objects. The Base class of the hierachy stores a typelist identifying the signature of the constructors to be called...
4
by: David Zha0 | last post by:
Hi, "when we call a virtual method, the runtime will check the instance who called the method and then choose the suitable override method, this may causes the performance drop down", is this...
17
by: Jess | last post by:
Hello, If I have a class that has virtual but non-pure declarations, like class A{ virtual void f(); }; Then is A still an abstract class? Do I have to have "virtual void f() = 0;"...
6
by: Miguel Guedes | last post by:
Hello, I recently read an interview with Bjarne Stroustrup in which he says that pure abstract classes should *not* contain any data. However, I have found that at times situations are when it...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.