C++0x "auto" equivalence in non-0x? (function needs to return undeterminedtype value)

Discussion in 'C++' started by Qi, May 6, 2011.

  1. Qi

    Qi Guest

    What I want to do is,

    template <typename T>
    void process(const T & value);

    UndeterminedType generate();

    "generate" may return value in various types, which is unknown when it's
    called. What's determined is that all types are already known and
    defined.
    So I know "generate" can return a value in type A, B or C, but I don't
    know which one it exactly is.

    The result from "generate" is only used to feed "process", I don't need
    to store it. But it will be good if I can store it.

    Seems "auto" keyword in C++0x is introduced to solve that problem.

    My question is, how to do the equivalence in non-0x C++?

    The reason I won't use 0x is seems current compilers can't support it
    well. VC only supports "auto" from version 10 while I'm using 9!


    --
    WQ
     
    Qi, May 6, 2011
    #1
    1. Advertising

  2. Qi

    m0shbear Guest

    Re: C++0x "auto" equivalence in non-0x? (function needs to returnundetermined type value)

    On May 5, 10:56 pm, Qi <> wrote:
    > What I want to do is,
    >
    > template <typename T>
    > void process(const T & value);
    >
    > UndeterminedType generate();
    >
    > "generate" may return value in various types, which is unknown when it's
    > called. What's determined is that all types are already known and
    > defined.
    > So I know "generate" can return a value in type A, B or C, but I don't
    > know which one it exactly is.
    >
    > The result from "generate" is only used to feed "process", I don't need
    > to store it. But it will be good if I can store it.
    >
    > Seems "auto" keyword in C++0x is introduced to solve that problem.
    >
    > My question is, how to do the equivalence in non-0x C++?
    >
    > The reason I won't use 0x is seems current compilers can't support it
    > well. VC only supports "auto" from version 10 while I'm using 9!
    >
    > --
    > WQ


    Why not make generate a template function and call generate<T>(...)?
     
    m0shbear, May 6, 2011
    #2
    1. Advertising

  3. Qi

    Qi Guest

    Re: C++0x "auto" equivalence in non-0x? (function needs to returnundetermined type value)

    On 2011-5-6 11:18, m0shbear wrote:

    > Why not make generate a template function and call generate<T>(...)?


    Because T is undetermined when calling "generate".
    Your that kind of template function needs T to be determined.


    --
    WQ
     
    Qi, May 6, 2011
    #3
  4. Re: C++0x "auto" equivalence in non-0x? (function needs to returnundetermined type value)

    On May 5, 8:25 pm, Qi <> wrote:
    > On 2011-5-6 11:18, m0shbear wrote:
    >
    > > Why not make generate a template function and call generate<T>(...)?

    >
    > Because T is undetermined when calling "generate".
    > Your that kind of template function needs T to be determined.


    This can be a very hard problem to solve. I've looked through the
    large and hacky codebase in boost that tries to support pseudo-lambda
    functions with its _1, _2, and _3. This is an impossible problem to
    solve in all cases, a pain in the ass for suitably general cases, and
    maybe doable for easy cases. I would need to know specific details to
    offer further advice, though I would suggest reworking it so you don't
    have this requirement if at all reasonable.
     
    Joshua Maurice, May 6, 2011
    #4
  5. Qi

    Qi Guest

    Re: C++0x "auto" equivalence in non-0x? (function needs to returnundetermined type value)

    On 2011-5-6 13:15, Joshua Maurice wrote:

    > This can be a very hard problem to solve. I've looked through the
    > large and hacky codebase in boost that tries to support pseudo-lambda
    > functions with its _1, _2, and _3. This is an impossible problem to
    > solve in all cases, a pain in the ass for suitably general cases, and
    > maybe doable for easy cases. I would need to know specific details to
    > offer further advice, though I would suggest reworking it so you don't
    > have this requirement if at all reasonable.


    Yes, if there is no solution, I will change my design, not very
    difficult but it will be a little ugly.

    Don't know what details you need.
    I would give some pseudo code to explain more.

    struct A { void run() const; };
    struct B { void run() const; };
    struct C { void run() const; };

    template <typename T>
    void process(const T & value);
    {
    value.run();
    }

    /*****************************
    How to deal with SomeType?
    In C++0x, it can be "auto" (hope I'm correct,
    I never tried 0x though),
    But how to do it in non-0x?
    *****************************/
    SomeType generate()
    {
    switch(random number) {
    case 0:
    return A();

    case 1:
    return B();

    default:
    return C();
    }
    }

    void main()
    {
    process(generate()); // here is how I want to use "generate"
    }

    --
    WQ
     
    Qi, May 6, 2011
    #5
  6. Qi

    Kai-Uwe Bux Guest

    Re: C++0x "auto" equivalence in non-0x? (function needs to return undetermined type value)

    Qi wrote:

    > What I want to do is,
    >
    > template <typename T>
    > void process(const T & value);
    >
    > UndeterminedType generate();
    >
    > "generate" may return value in various types, which is unknown when it's
    > called. What's determined is that all types are already known and
    > defined.
    > So I know "generate" can return a value in type A, B or C, but I don't
    > know which one it exactly is.
    >
    > The result from "generate" is only used to feed "process", I don't need
    > to store it. But it will be good if I can store it.
    >
    > Seems "auto" keyword in C++0x is introduced to solve that problem.


    I thought, the "auto" keyword will still require that the compiler can
    deduce the type at compile time.

    > My question is, how to do the equivalence in non-0x C++?
    >
    > The reason I won't use 0x is seems current compilers can't support it
    > well. VC only supports "auto" from version 10 while I'm using 9!



    Best,

    Kai-Uwe Bux
     
    Kai-Uwe Bux, May 6, 2011
    #6
  7. Qi

    SG Guest

    Re: C++0x "auto" equivalence in non-0x? (function needs to returnundetermined type value)

    On 6 Mai, 07:50, Qi wrote:
    >
    > /*****************************
    > How to deal with SomeType?
    > In C++0x, it can be "auto" (hope I'm correct,
    > I never tried 0x though),
    > But how to do it in non-0x?
    > *****************************/
    > SomeType generate()
    > {
    >    switch(random number) {
    >      case 0:
    >           return A();
    >
    >      case 1:
    >           return B();
    >
    >      default:
    >           return C();
    >    }
    > }


    It seems you misunderstood 'auto'. There is nothing dynamic about
    'auto'. For functions, 'auto' is part of the new function declaration
    syntax:

    double foo(int,string); // old syntax (still valid)
    auto foo(int,string) -> double; // new syntax

    The only difference is that the return type is mentioned last in the
    declaration.

    > void main()
    > {
    >    process(generate()); // here is how I want to use "generate"
    > }


    This cannot work, neither in C++0x nor in C++98. generate must have
    some return type known at compile time. You want to change the type at
    runtime. But template argument deduction happens at compile-time. So,
    you would need some kind of type-erasing wrapper (boost::variant) and
    manually perform some kind of dispatch to select the correct process
    function. You can't magically use a runtime type information to select
    the right process function at compile-time.

    SG
     
    SG, May 6, 2011
    #7
  8. Qi

    Kai-Uwe Bux Guest

    Re: C++0x "auto" equivalence in non-0x? (function needs to return undetermined type value)

    Qi wrote:

    > On 2011-5-6 13:15, Joshua Maurice wrote:
    >
    >> This can be a very hard problem to solve. I've looked through the
    >> large and hacky codebase in boost that tries to support pseudo-lambda
    >> functions with its _1, _2, and _3. This is an impossible problem to
    >> solve in all cases, a pain in the ass for suitably general cases, and
    >> maybe doable for easy cases. I would need to know specific details to
    >> offer further advice, though I would suggest reworking it so you don't
    >> have this requirement if at all reasonable.

    >
    > Yes, if there is no solution, I will change my design, not very
    > difficult but it will be a little ugly.
    >
    > Don't know what details you need.
    > I would give some pseudo code to explain more.
    >
    > struct A { void run() const; };
    > struct B { void run() const; };
    > struct C { void run() const; };
    >
    > template <typename T>
    > void process(const T & value);
    > {
    > value.run();
    > }
    >
    > /*****************************
    > How to deal with SomeType?
    > In C++0x, it can be "auto" (hope I'm correct,
    > I never tried 0x though),
    > But how to do it in non-0x?
    > *****************************/
    > SomeType generate()
    > {
    > switch(random number) {
    > case 0:
    > return A();
    >
    > case 1:
    > return B();
    >
    > default:
    > return C();
    > }
    > }
    >
    > void main()
    > {
    > process(generate()); // here is how I want to use "generate"
    > }
    >


    It seems that the above could be rewritten as:

    struct A { void run() const; };
    struct B { void run() const; };
    struct C { void run() const; };

    template <typename T>
    void process(const T & value);
    {
    value.run();
    }

    void generate()
    {
    switch(random number) {
    case 0: {
    A x;
    process(x);
    }
    case 1: {
    B x;
    process(x);
    }
    default: {
    C x;
    process(x);
    }
    }
    }

    int main()
    {
    generate();
    }


    Alternatively, you could make A, B, C inherit from a common base and make
    run() a virtual method. You could also use duck typing: keep A, B, and C
    unrelated but provide a class Runnable that can accommodate values of A, B,
    and C:

    #include <algorithm>
    using std::swap;

    class Runnable {

    struct base {

    virtual
    ~base ( void ) {}

    virtual
    void run ( void ) {}

    virtual
    base * clone ( void ) {}

    };

    template < typename A >
    struct derived : base {

    A data;

    derived ( A const & a )
    : data ( a )
    {}

    virtual
    void run ( void ) {
    data.run();
    }

    virtual
    derived * clone ( void ) {
    return ( new derived ( data ) );
    }

    };

    base * the_ptr;

    public:

    template < typename A >
    Runnable ( A const & a )
    : the_ptr( new derived<A>( a ) )
    {}

    Runnable ( Runnable const & other )
    : the_ptr ( other.the_ptr->clone() )
    {}

    ~Runnable ( void ) {
    delete ( the_ptr );
    }

    friend
    void swap ( Runnable & lhs, Runnable & rhs ) {
    swap( lhs.the_ptr, rhs.the_ptr );
    }

    Runnable & operator= ( Runnable other ) {
    swap( *this, other );
    return ( *this );
    }

    void run ( void ) {
    the_ptr->run();
    }

    };


    #include <iostream>
    #include <ostream>

    struct A {

    void run ( void ) {
    std::cout << "A\n";
    }

    };

    struct B {

    void run ( void ) {
    std::cout << "B\n";
    }

    };

    Runnable generate ( int i ) {
    if ( i % 2 ) {
    return ( A() );
    } else {
    return ( B() );
    }
    }

    int main ( void ) {
    for ( int i = 0; i < 10; ++i ) {
    generate(i).run();
    }
    }


    Best,

    Kai-Uwe Bux
     
    Kai-Uwe Bux, May 6, 2011
    #8
  9. Qi

    Qi Guest

    Re: C++0x "auto" equivalence in non-0x? (function needs to returnundetermined type value)

    On 2011-5-6 14:54, SG wrote:
    >
    > This cannot work, neither in C++0x nor in C++98. generate must have
    > some return type known at compile time. You want to change the type at
    > runtime. But template argument deduction happens at compile-time. So,
    > you would need some kind of type-erasing wrapper (boost::variant) and
    > manually perform some kind of dispatch to select the correct process
    > function. You can't magically use a runtime type information to select
    > the right process function at compile-time.


    Seems I was confused by the runtime behavior in function "generate".

    Now I get it.

    I will have to "process" manually for corresponding type.


    --
    WQ
     
    Qi, May 6, 2011
    #9
  10. Qi

    Qi Guest

    Re: C++0x "auto" equivalence in non-0x? (function needs to returnundetermined type value)

    On 2011-5-6 15:00, Kai-Uwe Bux wrote:
    >
    > Alternatively, you could make A, B, C inherit from a common base and make
    > run() a virtual method. You could also use duck typing: keep A, B, and C
    > unrelated but provide a class Runnable that can accommodate values of A, B,
    > and C:


    I would like avoid virtual functions since the processing are quite
    cpu intensive.

    I would prefer compile time polymorphism over runtime virtual functions.


    --
    WQ
     
    Qi, May 6, 2011
    #10
  11. Qi

    m0shbear Guest

    Re: C++0x "auto" equivalence in non-0x? (function needs to returnundetermined type value)

    On May 6, 3:56 am, Qi <> wrote:
    > On 2011-5-6 15:00, Kai-Uwe Bux wrote:
    >
    >
    >
    > > Alternatively, you could make A, B, C inherit from a common base and make
    > > run() a virtual method. You could also use duck typing: keep A, B, and C
    > > unrelated but provide a class Runnable that can accommodate values of A, B,
    > > and C:

    >
    > I would like avoid virtual functions since the processing are quite
    > cpu intensive.
    >
    > I would prefer compile time polymorphism over runtime virtual functions.


    Boost::any isn't virtual. But you have to try-catch bad casts to infer
    type.
     
    m0shbear, May 6, 2011
    #11
  12. Re: C++0x "auto" equivalence in non-0x? (function needs to return undetermined type value)

    Qi wrote:

    > What I want to do is,
    >
    > template <typename T>
    > void process(const T & value);
    >
    > UndeterminedType generate();
    >
    > "generate" may return value in various types, which is unknown when it's
    > called. What's determined is that all types are already known and
    > defined.
    > So I know "generate" can return a value in type A, B or C, but I don't
    > know which one it exactly is.
    >
    > The result from "generate" is only used to feed "process", I don't need
    > to store it. But it will be good if I can store it.
    >
    > Seems "auto" keyword in C++0x is introduced to solve that problem.
    >


    Looks like you are confused. "auto" has nothing to do with that. What you
    want to use is a boost::variant<A, B, C> or equivalent.
     
    Johannes Schaub, May 6, 2011
    #12
  13. Re: C++0x "auto" equivalence in non-0x? (function needs to return undetermined type value)

    m0shbear wrote:

    > On May 6, 3:56 am, Qi <> wrote:
    >> On 2011-5-6 15:00, Kai-Uwe Bux wrote:
    >>
    >>
    >>
    >> > Alternatively, you could make A, B, C inherit from a common base and
    >> > make run() a virtual method. You could also use duck typing: keep A, B,
    >> > and C unrelated but provide a class Runnable that can accommodate
    >> > values of A, B, and C:

    >>
    >> I would like avoid virtual functions since the processing are quite
    >> cpu intensive.
    >>
    >> I would prefer compile time polymorphism over runtime virtual functions.

    >
    > Boost::any isn't virtual. But you have to try-catch bad casts to infer
    > type.


    That's plain wrong. boost::any performs type-erasure, and needs runtime
    polymorphism to remember the dynamic type of the stored object. It uses
    virtual functions (clone, etc..).

    boost::any is inefficient, and is designed to be *simple*. It doesn't do
    stack-allocation, so it will also use the heap.
     
    Johannes Schaub, May 6, 2011
    #13
  14. Re: C++0x "auto" equivalence in non-0x? (function needs to returnundetermined type value)

    Hi,

    Qi wrote:
    > On 2011-5-6 15:00, Kai-Uwe Bux wrote:
    >>
    >> Alternatively, you could make A, B, C inherit from a common base and make
    >> run() a virtual method. You could also use duck typing: keep A, B, and C
    >> unrelated but provide a class Runnable that can accommodate values of
    >> A, B,
    >> and C:

    >
    > I would like avoid virtual functions since the processing are quite
    > cpu intensive.


    oh, you are counting clock cycles. Hopefully you counted the right ones.

    > I would prefer compile time polymorphism over runtime virtual functions.


    Anyway, you will never be able to use compile time polymorphism if the
    type decision is taken at run time (in the generate function).


    Marcel
     
    Marcel Müller, May 6, 2011
    #14
  15. Qi

    James Kanze Guest

    Re: C++0x "auto" equivalence in non-0x? (function needs to returnundetermined type value)

    On May 6, 3:56 am, Qi <> wrote:
    > What I want to do is,


    > template <typename T>
    > void process(const T & value);


    > UndeterminedType generate();


    > "generate" may return value in various types, which is unknown when it's
    > called. What's determined is that all types are already known and
    > defined.
    > So I know "generate" can return a value in type A, B or C, but I don't
    > know which one it exactly is.


    > The result from "generate" is only used to feed "process", I don't need
    > to store it. But it will be good if I can store it.


    > Seems "auto" keyword in C++0x is introduced to solve that problem.


    No. "auto" is purely a compile time analysis. As are
    templates. The only question is what type "generate" is
    declared to return.

    --
    James Kanze
     
    James Kanze, May 8, 2011
    #15
  16. Qi

    m0shbear Guest

    Re: C++0x "auto" equivalence in non-0x? (function needs to returnundetermined type value)

    On May 6, 8:32 am, Johannes Schaub <>
    wrote:
    > m0shbear wrote:
    > > On May 6, 3:56 am, Qi <> wrote:
    > >> On 2011-5-6 15:00, Kai-Uwe Bux wrote:

    >
    > >> > Alternatively, you could make A, B, C inherit from a common base and
    > >> > make run() a virtual method. You could also use duck typing: keep A,B,
    > >> > and C unrelated but provide a class Runnable that can accommodate
    > >> > values of A, B, and C:

    >
    > >> I would like avoid virtual functions since the processing are quite
    > >> cpu intensive.

    >
    > >> I would prefer compile time polymorphism over runtime virtual functions.

    >
    > > Boost::any isn't virtual. But you have to try-catch bad casts to infer
    > > type.

    >
    > That's plain wrong. boost::any performs type-erasure, and needs runtime
    > polymorphism to remember the dynamic type of the stored object. It uses
    > virtual functions (clone, etc..).
    >
    > boost::any is inefficient, and is designed to be *simple*. It doesn't do
    > stack-allocation, so it will also use the heap.


    My bad. I'm still somewhat of a n00b when it comes to boost. In
    hindsight, I should've said boost::variant, as boost::any looks like a
    dynamic_cast-checked conversion from void*.
     
    m0shbear, May 9, 2011
    #16
    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. =?Utf-8?B?S2VubmV0aCBQ?=

    MySql's equivalence to MsSql's 'TOP' command/function/clause

    =?Utf-8?B?S2VubmV0aCBQ?=, Jan 8, 2005, in forum: ASP .Net
    Replies:
    1
    Views:
    11,773
    John Timney \(ASP.NET MVP\)
    Jan 8, 2005
  2. Peng Yu
    Replies:
    1
    Views:
    323
    Sarah Thompson
    Jul 12, 2003
  3. Greenhorn
    Replies:
    15
    Views:
    840
    Keith Thompson
    Mar 6, 2005
  4. Jeremy Ralph
    Replies:
    6
    Views:
    469
    Mike Treseler
    Apr 17, 2007
  5. linkswanted
    Replies:
    1
    Views:
    938
Loading...

Share This Page