Abstract base class requires a virtual template: fixes?

Discussion in 'C++' started by Dom Jackson, Jun 27, 2007.

  1. Dom Jackson

    Dom Jackson Guest

    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
    Dom Jackson, Jun 27, 2007
    #1
    1. Advertising

  2. Dom Jackson

    dasjotre Guest

    On 27 Jun, 12:16, Dom Jackson <> 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
    dasjotre, Jun 27, 2007
    #2
    1. Advertising

  3. 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 TListIni> struct
    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<IntList> myoperation;

    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
    Michael DOUBEZ, Jun 27, 2007
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Luis G Hernandez

    Abstract base class + virtual Method

    Luis G Hernandez, Mar 5, 2004, in forum: C++
    Replies:
    5
    Views:
    423
    Jorge Rivera
    Mar 6, 2004
  2. Roy Smith
    Replies:
    5
    Views:
    410
    Duane Hebert
    Nov 18, 2005
  3. Replies:
    2
    Views:
    557
  4. Hicham Mouline
    Replies:
    1
    Views:
    592
    Victor Bazarov
    Apr 20, 2009
  5. Marcel Müller
    Replies:
    2
    Views:
    116
    Marcel Müller
    Mar 15, 2014
Loading...

Share This Page