universal selector

Discussion in 'C++' started by Vladimir, Nov 26, 2004.

  1. Vladimir

    Vladimir Guest

    Hello!

    I'd like to select one of possible entities according to a given index:

    select(index, A, B)

    would return A if index is 0, B if index is (or greater than) 1.

    so i write:

    template<typename T> T select(int index, T a, T b)
    {
    return (index == 0) ? a : b;
    }

    this works fine when calling selected function:

    select(index, somefunction0, somefunction1)(args...)

    but fails for class member functions - what should I do?
    Ideally I want it universal, without the need
    to rewrite select() for each class.

    --
    Vladimir
     
    Vladimir, Nov 26, 2004
    #1
    1. Advertising

  2. On 26 Nov 2004 07:45:30 -0800, (Vladimir) wrote:

    >Hello!
    >
    >I'd like to select one of possible entities according to a given index:
    >
    >select(index, A, B)
    >
    >would return A if index is 0, B if index is (or greater than) 1.
    >
    >so i write:
    >
    >template<typename T> T select(int index, T a, T b)
    >{
    > return (index == 0) ? a : b;
    >}
    >
    >this works fine when calling selected function:
    >
    >select(index, somefunction0, somefunction1)(args...)
    >
    >but fails for class member functions - what should I do?
    >Ideally I want it universal, without the need
    >to rewrite select() for each class.


    You cannot call non-static member functions without an object.

    --
    Bob Hairgrove
     
    Bob Hairgrove, Nov 26, 2004
    #2
    1. Advertising

  3. * Vladimir:
    > Hello!
    >
    > I'd like to select one of possible entities according to a given index:
    >
    > select(index, A, B)
    >
    > would return A if index is 0, B if index is (or greater than) 1.
    >
    > so i write:
    >
    > template<typename T> T select(int index, T a, T b)
    > {
    > return (index == 0) ? a : b;
    > }
    >
    > this works fine when calling selected function:
    >
    > select(index, somefunction0, somefunction1)(args...)
    >
    > but fails for class member functions - what should I do?
    > Ideally I want it universal, without the need
    > to rewrite select() for each class.


    #include <iostream>
    #include "generalmaker.h"
    #include <string>
    #include <list>

    using namespace std;

    #include <iostream>

    template<typename T> T select(int index, T a, T b)
    {
    return (index == 0) ? a : b;
    }

    class X
    {
    public:
    void a( char const s[] ) const
    {
    std::cout << "a: " << s << std::endl;
    }

    void b( char const s[] ) const
    {
    std::cout << "b: " << s << std::endl;
    }
    };

    int main()
    {
    X o;

    (o.*select( 0, X::a, X::b ))( "Silly syntax, yes." );
    }

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Nov 26, 2004
    #3
  4. Vladimir wrote:
    > Hello!
    >
    > I'd like to select one of possible entities according to a given index:
    >
    > select(index, A, B)
    >
    > would return A if index is 0, B if index is (or greater than) 1.
    >
    > so i write:
    >
    > template<typename T> T select(int index, T a, T b)
    > {
    > return (index == 0) ? a : b;
    > }
    >
    > this works fine when calling selected function:
    >
    > select(index, somefunction0, somefunction1)(args...)
    >
    > but fails for class member functions - what should I do?
    > Ideally I want it universal, without the need
    > to rewrite select() for each class.


    The code below compiled fine. What exactly is your problem ?

    template<typename T> T select(int index, T a, T b)
    {
    return (index == 0) ? a : b;
    }

    struct X
    {
    void f1() {}
    void f2() {}
    };

    int main()
    {
    void (X::*z)() = select( 0, &X::f1, &X::f2 );

    X q;

    (q.*(select( 1, &X::f1, &X::f2 )))();
    (q.*z)();
    }
     
    Gianni Mariani, Nov 26, 2004
    #4
  5. Vladimir

    Guest

    (Vladimir) wrote in message news:<>...
    > Hello!
    >
    > I'd like to select one of possible entities according to a given index:
    >
    > select(index, A, B)
    >
    > would return A if index is 0, B if index is (or greater than) 1.
    >
    > so i write:
    >
    > template<typename T> T select(int index, T a, T b)
    > {
    > return (index == 0) ? a : b;
    > }
    >
    > this works fine when calling selected function:
    >
    > select(index, somefunction0, somefunction1)(args...)
    >
    > but fails for class member functions - what should I do?
    > Ideally I want it universal, without the need
    > to rewrite select() for each class.


    #include <iostream>

    template<typename T> T select(int index, T a, T b)
    {
    return (index == 0) ? a : b;
    }

    class test
    {
    int val;
    public:
    test(int inVal):val(inVal) {}
    int testFunc() {return val;}
    };


    int main(int argc, char* argv[])
    {
    test one(1);
    test two(2);

    std::cout << select(0,one.testFunc() ,two.testFunc() ) << std::endl ;

    std::cout << select(1,one.testFunc() ,two.testFunc() ) << std::endl ;

    return 0;
    }

    Output
    1
    2

    Ok, I'm not quite getting the problem.
    Socks
     
    , Nov 26, 2004
    #5
  6. * :
    > (Vladimir) wrote in message news:<>...
    > > Hello!
    > >
    > > I'd like to select one of possible entities according to a given index:
    > >
    > > select(index, A, B)
    > >
    > > would return A if index is 0, B if index is (or greater than) 1.
    > >
    > > so i write:
    > >
    > > template<typename T> T select(int index, T a, T b)
    > > {
    > > return (index == 0) ? a : b;
    > > }
    > >
    > > this works fine when calling selected function:
    > >
    > > select(index, somefunction0, somefunction1)(args...)
    > >
    > > but fails for class member functions - what should I do?
    > > Ideally I want it universal, without the need
    > > to rewrite select() for each class.

    >
    > #include <iostream>
    >
    > template<typename T> T select(int index, T a, T b)
    > {
    > return (index == 0) ? a : b;
    > }
    >
    > class test
    > {
    > int val;
    > public:
    > test(int inVal):val(inVal) {}
    > int testFunc() {return val;}
    > };
    >
    >
    > int main(int argc, char* argv[])
    > {
    > test one(1);
    > test two(2);
    >
    > std::cout << select(0,one.testFunc() ,two.testFunc() ) << std::endl ;
    >
    > std::cout << select(1,one.testFunc() ,two.testFunc() ) << std::endl ;
    >
    > return 0;
    > }
    >
    > Output
    > 1
    > 2
    >
    > Ok, I'm not quite getting the problem.


    Each of your select calls makes two function calls for the arguments.

    The OP wants just one, namely a call of the selected function.

    That's easily achieved, as Gianni Mariani and I have shown earlier.

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Nov 26, 2004
    #6
  7. Vladimir

    Vladimir Guest

    Bob Hairgrove <> wrote:
    > >this works fine when calling selected function:
    > >
    > >select(index, somefunction0, somefunction1)(args...)
    > >
    > >but fails for class member functions - what should I do?
    > >Ideally I want it universal, without the need
    > >to rewrite select() for each class.

    >
    > You cannot call non-static member functions without an object.


    so, why

    select(index, obj.somefunction0, obj.somefunction1)(args...)

    doesn't work as expected?

    Why there is so much difference between functions and
    member functions? Aren't templates supposed to be matched
    to any type? Is it compiler implementation issue?

    --
    Vladimir
     
    Vladimir, Nov 27, 2004
    #7
  8. Vladimir

    Vladimir Guest

    Gianni Mariani <> wrote:
    > >
    > > select(index, somefunction0, somefunction1)(args...)
    > >

    >
    > The code below compiled fine. What exactly is your problem ?
    >
    > (q.*(select( 1, &X::f1, &X::f2 )))();


    My problem is that we usually write helper functions
    to simplify coding and improve readability.
    This also means less typing which unfortunately
    isn't the case with the above solution. :(

    Well this code works, but instead of quickly selecting
    and calling member function we have to do scope resolution,
    address taking, dereferencing and lots of brackets...

    --
    Vladimir
     
    Vladimir, Nov 27, 2004
    #8
  9. On 27 Nov 2004 07:51:20 -0800, (Vladimir) wrote:

    >Bob Hairgrove <> wrote:
    >> >this works fine when calling selected function:
    >> >
    >> >select(index, somefunction0, somefunction1)(args...)
    >> >
    >> >but fails for class member functions - what should I do?
    >> >Ideally I want it universal, without the need
    >> >to rewrite select() for each class.

    >>
    >> You cannot call non-static member functions without an object.

    >
    >so, why
    >
    >select(index, obj.somefunction0, obj.somefunction1)(args...)
    >
    >doesn't work as expected?


    It's simply the wrong syntax for calling pointer to member. Try this:

    (obj.*(select(index, somefunction0, somefunction1)))(args...)

    >Why there is so much difference between functions and
    >member functions? Aren't templates supposed to be matched
    >to any type? Is it compiler implementation issue?


    As you can see, everything inside the brackets beginning with
    "select(" is just the way you had it. Templates work fine. It's
    afterwards where you have trouble. RTFM about pointer to member. They
    are actually a kind of offset into the class function list, not real
    pointers.

    Using an index to select functions seems to me not very
    object-oriented. Maybe you could rethink the design and use virtual
    functions instead.

    --
    Bob Hairgrove
     
    Bob Hairgrove, Nov 28, 2004
    #9
  10. Vladimir

    Old Wolf Guest

    (Vladimir) wrote:
    > Gianni Mariani <> wrote:
    > > >
    > > > select(index, somefunction0, somefunction1)(args...)
    > > >

    > >
    > > The code below compiled fine. What exactly is your problem ?
    > >
    > > (q.*(select( 1, &X::f1, &X::f2 )))();

    >
    > My problem is that we usually write helper functions
    > to simplify coding and improve readability.
    > This also means less typing which unfortunately
    > isn't the case with the above solution. :(
    >
    > Well this code works, but instead of quickly selecting
    > and calling member function we have to do scope resolution,
    > address taking, dereferencing and lots of brackets...


    Then, don't use silly obfuscations like this select() function.
    It might save you a couple of characters from time to time but
    it makes the code harder to read for anybody who doesn't know
    what the function does (or even yourself, if you come back to
    it in future and forget what the select criterion was). FWIW
    it also collides with the POSIX 'select' function, if you ever
    port your code to Unix systems.
     
    Old Wolf, Nov 28, 2004
    #10
  11. Vladimir

    Vladimir Guest

    Old Wolf wrote:
    > Then, don't use silly obfuscations like this select() function.


    Why obfuscations? Isn't it nice to get for example
    traffic light color this way:

    color = select(number, green, yellow, red);

    This is done without cumbersome "?:" or switch() statements,
    or declaring some data structure in the middle of nowhere :)

    It works fine with everything except member functions.
    Maybe I should redesign my code. Anyway, here's my task.

    I often have 3 similar methods (same arguments) in a class
    which calculate a function with different accuracy:

    class {
    ...
    double precise(args);
    double approx0(args); // zero order approximation
    double approx1(args); // first order approximation
    };

    I have to call them in a loop with other code:

    for(int i = 0; i < 3; i++) {
    select(i, precise, approx0, approx1)(args);
    ...
    /* lots of other code */
    }

    so on each iteration appropriate member function should be
    called except it doesn't work with simple syntax.
    Do I have a wrong approach, or maybe not object-oriented enough?

    --
    Vladimir
     
    Vladimir, Nov 29, 2004
    #11
  12. Vladimir wrote:
    > Old Wolf wrote:
    >
    >>Then, don't use silly obfuscations like this select() function.

    >
    >
    > Why obfuscations? Isn't it nice to get for example
    > traffic light color this way:
    >
    > color = select(number, green, yellow, red);
    >
    > This is done without cumbersome "?:" or switch() statements,
    > or declaring some data structure in the middle of nowhere :)
    >
    > It works fine with everything except member functions.
    > Maybe I should redesign my code. Anyway, here's my task.
    >
    > I often have 3 similar methods (same arguments) in a class
    > which calculate a function with different accuracy:
    >
    > class {
    > ...
    > double precise(args);
    > double approx0(args); // zero order approximation
    > double approx1(args); // first order approximation
    > };
    >
    > I have to call them in a loop with other code:
    >
    > for(int i = 0; i < 3; i++) {
    > select(i, precise, approx0, approx1)(args);
    > ...
    > /* lots of other code */
    > }
    >
    > so on each iteration appropriate member function should be
    > called except it doesn't work with simple syntax.
    > Do I have a wrong approach, or maybe not object-oriented enough?


    There is nothing wrong with your approach. The language simply does not
    support it quite like you want it to.

    I concur that you should use a different name (select is an important
    posix function).

    If C++ had a "typeof" operator you could do this below. However, this
    is not standard (only works with GCC).

    template <typename T> struct H {
    typedef T type;
    };

    #define choosefun(A,B,C,D)\
    ((A).*((B) ? &H<typeof(A)>::type::C : &H<typeof(A)>::type::D))

    struct X {
    double precise();
    double approx0(); // zero order approximation
    double approx1(); // first order approximation
    };

    int main()
    {
    X x;

    choosefun(x,true,approx0,approx1)();
    }
     
    Gianni Mariani, Nov 29, 2004
    #12
    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. Jens Mander
    Replies:
    0
    Views:
    513
    Jens Mander
    Jun 10, 2005
  2. Jens Mander
    Replies:
    2
    Views:
    1,397
    Jerry Coffin
    Sep 1, 2005
  3. Jaison

    MSDN Universal for only $1499

    Jaison, Jul 16, 2003, in forum: ASP .Net
    Replies:
    0
    Views:
    295
    Jaison
    Jul 16, 2003
  4. DMan

    MSDN Universal question

    DMan, Apr 23, 2004, in forum: ASP .Net
    Replies:
    1
    Views:
    369
    Mark Fitzpatrick
    Apr 23, 2004
  5. Jan Clemens Faerber

    Universal Selector to gain browser uniformity

    Jan Clemens Faerber, Apr 4, 2013, in forum: HTML
    Replies:
    4
    Views:
    359
    Jan Clemens Faerber
    Apr 5, 2013
Loading...

Share This Page