Pointer to operator for builtin types

Discussion in 'C++' started by =?iso-8859-1?q?Erik_Wikstr=F6m?=, Dec 15, 2006.

  1. Is there some way to get a function-pointer to the operators of the
    builtin types? In the following example I have a generic function which
    applies an operator on two values, however it does not work on builtin
    types, is there a way to make this work?

    struct Test
    {
    int i;
    Test(int i_) : i(i_) { }
    Test operator+(Test& t) { return Test(i + t.i); }
    Test operator-(Test& t) { return Test(i - t.i); }
    operator int() { return i; }
    };

    template<class T>
    T operate(T& t1, T& t2, T (T::*func)(T&))
    {
    return (t1.*func)(t2);
    }


    int main() {
    Test test1(1);
    Test test2(2);
    Test test3 = operate(test1, test2, &Test::eek:perator+);
    Test test4 = operate(test1, test2, &Test::eek:perator-);

    /*
    int i1 = 1;
    int i2 = 2;
    int i3 = operate(i1, i2, ???);
    int i4 = operate(i1, i2, ???)
    */
    }

    --
    Erik Wikström
    =?iso-8859-1?q?Erik_Wikstr=F6m?=, Dec 15, 2006
    #1
    1. Advertising

  2. =?iso-8859-1?q?Erik_Wikstr=F6m?=

    John Carson Guest

    "Erik Wikström" <> wrote in message
    news:
    > Is there some way to get a function-pointer to the operators of the
    > builtin types?


    No.

    > In the following example I have a generic function
    > which applies an operator on two values, however it does not work on
    > builtin types, is there a way to make this work?
    > struct Test
    > {
    > int i;
    > Test(int i_) : i(i_) { }
    > Test operator+(Test& t) { return Test(i + t.i); }
    > Test operator-(Test& t) { return Test(i - t.i); }
    > operator int() { return i; }
    > };
    > template<class T>
    > T operate(T& t1, T& t2, T (T::*func)(T&))
    > {
    > return (t1.*func)(t2);
    > }
    >
    >
    > int main() {
    > Test test1(1);
    > Test test2(2);
    > Test test3 = operate(test1, test2, &Test::eek:perator+);
    > Test test4 = operate(test1, test2, &Test::eek:perator-);
    >
    > /*
    > int i1 = 1;
    > int i2 = 2;
    > int i3 = operate(i1, i2, ???);
    > int i4 = operate(i1, i2, ???)
    > */
    > }


    Why do you want to call operator+? Why not just use +. This works for both
    built-in and class objects. The trick is to make class objects work like
    built-in ones, not the reverse.

    --
    John Carson
    John Carson, Dec 15, 2006
    #2
    1. Advertising

  3. =?iso-8859-1?q?Erik_Wikstr=F6m?=

    Ondra Holub Guest

    Erik Wikström napsal:
    > Is there some way to get a function-pointer to the operators of the
    > builtin types? In the following example I have a generic function which
    > applies an operator on two values, however it does not work on builtin
    > types, is there a way to make this work?
    >
    > struct Test
    > {
    > int i;
    > Test(int i_) : i(i_) { }
    > Test operator+(Test& t) { return Test(i + t.i); }
    > Test operator-(Test& t) { return Test(i - t.i); }
    > operator int() { return i; }
    > };
    >
    > template<class T>
    > T operate(T& t1, T& t2, T (T::*func)(T&))
    > {
    > return (t1.*func)(t2);
    > }
    >
    >
    > int main() {
    > Test test1(1);
    > Test test2(2);
    > Test test3 = operate(test1, test2, &Test::eek:perator+);
    > Test test4 = operate(test1, test2, &Test::eek:perator-);
    >
    > /*
    > int i1 = 1;
    > int i2 = 2;
    > int i3 = operate(i1, i2, ???);
    > int i4 = operate(i1, i2, ???)
    > */
    > }
    >
    > --
    > Erik Wikström


    AFAIK you cannot get pointer to operator+ for built-in types. But you
    can wrap such type in some class:

    #include <iostream>

    struct Test
    {
    int i;
    Test(int i_) : i(i_)
    { }
    Test operator+(const Test& t)
    {
    return Test(i + t.i);
    }
    Test operator-(const Test& t)
    {
    return Test(i - t.i);
    }
    operator int()
    {
    return i;
    }

    };

    template<typename T>
    class WrapType
    {
    public:
    WrapType(const T& data)
    : data_(data)
    {
    }

    T operator+(const T& value)
    {
    return data_ + value;
    }

    T operator-(const T& value)
    {
    return data_ - value;
    }

    private:
    T data_;
    };

    template<typename T, typename U>
    T operate(const T& t1, const T& t2, T (U::*func)(const T&))
    {
    return (U(t1).*func)(t2);
    }

    int main()
    {
    Test test1(1);
    Test test2(2);
    Test test3 = operate(test1, test2, &Test::eek:perator+);
    Test test4 = operate(test1, test2, &Test::eek:perator-);

    int i1 = 1;
    int i2 = 2;
    int i3 = operate(i1, i2, &WrapType<int>::eek:perator+);
    int i4 = operate(i1, i2, &WrapType<int>::eek:perator-);

    std::cout << i3 << " " << i4 << "\n";
    }

    If you need to call operate from some other template, there is no
    problem to use WrapType always:

    Test test3 = operate(test1, test2, &Wrap<Test>::eek:perator+);

    Of course, you would need to define also other operators in a WrapType
    template.
    Ondra Holub, Dec 15, 2006
    #3
  4. On Dec 15, 10:51 am, "John Carson" <>
    wrote:
    > "Erik Wikström" <> wrote in messagenews:
    >
    > > Is there some way to get a function-pointer to the operators of the
    > > builtin types?

    >
    >No.
    >
    > > In the following example I have a generic function
    > > which applies an operator on two values, however it does not work on
    > > builtin types, is there a way to make this work?
    > > struct Test
    > > {
    > > int i;
    > > Test(int i_) : i(i_) { }
    > > Test operator+(Test& t) { return Test(i + t.i); }
    > > Test operator-(Test& t) { return Test(i - t.i); }
    > > operator int() { return i; }
    > > };
    > > template<class T>
    > > T operate(T& t1, T& t2, T (T::*func)(T&))
    > > {
    > > return (t1.*func)(t2);
    > > }

    >
    > > int main() {
    > > Test test1(1);
    > > Test test2(2);
    > > Test test3 = operate(test1, test2, &Test::eek:perator+);
    > > Test test4 = operate(test1, test2, &Test::eek:perator-);

    >
    > > /*
    > > int i1 = 1;
    > > int i2 = 2;
    > > int i3 = operate(i1, i2, ???);
    > > int i4 = operate(i1, i2, ???)
    > > */
    > > }

    >
    > Why do you want to call operator+? Why not just use +. This works for both
    > built-in and class objects. The trick is to make class objects work like
    > built-in ones, not the reverse.



    Because then I can have a generic function which can operate on any
    type performing common operations,such as adding all elements in two
    vectors/lists/whatever, and if I instead want another operation
    performed I just change the function-pointer passed to the function. So
    I can easily add, multiply or whatever.

    I suppose that I could use functors, but then I would have to write a
    functor for each operation I'd like to perform, which is a bit more
    hassle than I'd like. Lambda-function would also have worked I guess.

    --
    Erik Wikström
    =?iso-8859-1?q?Erik_Wikstr=F6m?=, Dec 15, 2006
    #4
  5. =?iso-8859-1?q?Erik_Wikstr=F6m?=

    Ondra Holub Guest

    Erik Wikström napsal:
    > On Dec 15, 10:51 am, "John Carson" <>
    > wrote:
    > > "Erik Wikström" <> wrote in messagenews:
    > >
    > > > Is there some way to get a function-pointer to the operators of the
    > > > builtin types?

    > >
    > >No.
    > >
    > > > In the following example I have a generic function
    > > > which applies an operator on two values, however it does not work on
    > > > builtin types, is there a way to make this work?
    > > > struct Test
    > > > {
    > > > int i;
    > > > Test(int i_) : i(i_) { }
    > > > Test operator+(Test& t) { return Test(i + t.i); }
    > > > Test operator-(Test& t) { return Test(i - t.i); }
    > > > operator int() { return i; }
    > > > };
    > > > template<class T>
    > > > T operate(T& t1, T& t2, T (T::*func)(T&))
    > > > {
    > > > return (t1.*func)(t2);
    > > > }

    > >
    > > > int main() {
    > > > Test test1(1);
    > > > Test test2(2);
    > > > Test test3 = operate(test1, test2, &Test::eek:perator+);
    > > > Test test4 = operate(test1, test2, &Test::eek:perator-);

    > >
    > > > /*
    > > > int i1 = 1;
    > > > int i2 = 2;
    > > > int i3 = operate(i1, i2, ???);
    > > > int i4 = operate(i1, i2, ???)
    > > > */
    > > > }

    > >
    > > Why do you want to call operator+? Why not just use +. This works for both
    > > built-in and class objects. The trick is to make class objects work like
    > > built-in ones, not the reverse.

    >
    >
    > Because then I can have a generic function which can operate on any
    > type performing common operations,such as adding all elements in two
    > vectors/lists/whatever, and if I instead want another operation
    > performed I just change the function-pointer passed to the function. So
    > I can easily add, multiply or whatever.
    >
    > I suppose that I could use functors, but then I would have to write a
    > functor for each operation I'd like to perform, which is a bit more
    > hassle than I'd like. Lambda-function would also have worked I guess.
    >
    > --
    > Erik Wikström


    You do not have to write functors for all operations, they are already
    written. You can redefine operate this way:

    template<typename T, typename F>
    T operate2(const T& t1, const T& t2, const F& f)
    {
    return f(t1, t2);
    }

    And then use it so:

    int i5 = operate2(i1, i2, std::plus<int>());

    Test test5 = operate2(test1, test2, std::plus<Test>());

    One more headeris necessary: #include <functional>
    Ondra Holub, Dec 15, 2006
    #5
  6. =?iso-8859-1?q?Erik_Wikstr=F6m?=

    John Carson Guest

    "Erik Wikström" <> wrote in message
    news:
    > On Dec 15, 10:51 am, "John Carson"
    > <>
    > wrote:
    >> Why do you want to call operator+? Why not just use +. This works
    >> for both
    >> built-in and class objects. The trick is to make class objects work
    >> like
    >> built-in ones, not the reverse.

    >
    >
    > Because then I can have a generic function which can operate on any
    > type performing common operations,such as adding all elements in two
    > vectors/lists/whatever, and if I instead want another operation
    > performed I just change the function-pointer passed to the function.
    > So
    > I can easily add, multiply or whatever.
    >
    > I suppose that I could use functors, but then I would have to write a
    > functor for each operation I'd like to perform, which is a bit more
    > hassle than I'd like. Lambda-function would also have worked I guess.



    Have a look at the function objects available in the functional header.
    These include templates for plus, minus and various other things.

    --
    John Carson
    John Carson, Dec 15, 2006
    #6
  7. On Dec 15, 11:30 am, "Ondra Holub" <> wrote:
    > Erik Wikström napsal:
    >
    > > On Dec 15, 10:51 am, "John Carson" <>
    >>
    > > > Why do you want to call operator+? Why not just use +. This works for both
    > > > built-in and class objects. The trick is to make class objects work like
    > > > built-in ones, not the reverse.

    >
    > > Because then I can have a generic function which can operate on any
    > > type performing common operations,such as adding all elements in two
    > > vectors/lists/whatever, and if I instead want another operation
    > > performed I just change the function-pointer passed to the function. So
    > > I can easily add, multiply or whatever.

    >
    > > I suppose that I could use functors, but then I would have to write a
    > > functor for each operation I'd like to perform, which is a bit more
    > > hassle than I'd like. Lambda-function would also have worked I guess.

    >
    >You do not have to write functors for all operations, they are already
    > written. You can redefine operate this way:
    >
    > template<typename T, typename F>
    > T operate2(const T& t1, const T& t2, const F& f)
    > {
    > return f(t1, t2);
    >
    > }
    >
    > And then use it so:
    >
    > int i5 = operate2(i1, i2, std::plus<int>());
    >
    > Test test5 = operate2(test1, test2, std::plus<Test>());
    >
    > One more headeris necessary: #include <functional>


    Thank you, and John Carson, this solves my problem quite nicely.

    --
    Erik Wikström
    =?iso-8859-1?q?Erik_Wikstr=F6m?=, Dec 15, 2006
    #7
    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. Lonnie Princehouse

    Overriding builtin types

    Lonnie Princehouse, Mar 5, 2004, in forum: Python
    Replies:
    0
    Views:
    348
    Lonnie Princehouse
    Mar 5, 2004
  2. =?ISO-8859-1?Q?BJ=F6rn_Lindqvist?=

    subclassing builtin types

    =?ISO-8859-1?Q?BJ=F6rn_Lindqvist?=, Oct 8, 2004, in forum: Python
    Replies:
    2
    Views:
    3,484
    Alex Martelli
    Oct 8, 2004
  3. Replies:
    11
    Views:
    1,386
    James Kanze
    Jun 7, 2007
  4. Erik Wikström

    ostream operator<< and builtin types

    Erik Wikström, Feb 6, 2008, in forum: C++
    Replies:
    5
    Views:
    439
    Jerry Coffin
    Feb 17, 2008
  5. bdb112
    Replies:
    2
    Views:
    288
    Chris Torek
    Jul 2, 2011
Loading...

Share This Page