Function objects

Discussion in 'C++' started by anderberg, Dec 7, 2005.

  1. anderberg

    anderberg Guest

    Consider the following code,

    #include <iostream>

    struct Functor {
    void operator()(void) { std::cout << "Functor" << std::endl; }
    };

    int
    main(void)
    {
    Functor();
    return 0;
    }

    Why isn't operator() called for the temporary object that's created?

    --
    anderberg: People are just mutations. Some worse than others.
    anderberg, Dec 7, 2005
    #1
    1. Advertising

  2. * anderberg:
    > Consider the following code,
    >
    > #include <iostream>
    >
    > struct Functor {
    > void operator()(void) { std::cout << "Functor" << std::endl; }


    'void' as formal argument list is C-ism; don't.

    Also, should probably be 'const'.


    > };
    >
    > int
    > main(void)


    'void' as formal argument list is C-ism; don't.


    > {
    > Functor();
    > return 0;


    Not necessary in 'main', because 'main' is a special function.


    > }
    >
    > Why isn't operator() called for the temporary object that's created?


    Why should it?

    Try Functor()().

    --
    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, Dec 7, 2005
    #2
    1. Advertising

  3. anderberg wrote:
    > Consider the following code,
    >
    > #include <iostream>
    >
    > struct Functor {
    > void operator()(void) { std::cout << "Functor" << std::endl; }
    > };
    >
    > int
    > main(void)
    > {
    > Functor();
    > return 0;
    > }
    >
    > Why isn't operator() called for the temporary object that's created?
    >


    Because you didn't actually *call* it.

    Functor()

    is just creation of a temporary object. Now, add () to it and you get

    Functor()()

    which will result in a _call_.

    And, drop those 'void' from inside the parentheses. They're like sores.
    Ugh!

    V
    Victor Bazarov, Dec 7, 2005
    #3
  4. anderberg

    anderberg Guest

    On 2005-12-07, Alf P. Steinbach wrote:
    > * anderberg:
    >> Consider the following code,
    >>
    >> #include <iostream>
    >>
    >> struct Functor {
    >> void operator()(void) { std::cout << "Functor" << std::endl; }

    >
    > 'void' as formal argument list is C-ism; don't.


    Like to be explicit.

    > Also, should probably be 'const'.


    Of course, this wasn't a question about the code's "correctness".
    Just a simple case of illustrating my question.

    >> {
    >> Functor();
    >> return 0;

    >
    > Not necessary in 'main', because 'main' is a special function.


    See above.

    >> Why isn't operator() called for the temporary object that's created?

    >
    > Why should it?


    Functor a;
    a();

    I figured that Functor() would translate to something similar to
    the above. I guess I was wrong. But the question remains - why
    doesn't it?

    > Try Functor()().


    Thanks!

    --
    anderberg: People are just mutations. Some worse than others.
    anderberg, Dec 7, 2005
    #4
  5. anderberg

    Guest

    anderberg wrote:

    > On 2005-12-07, Alf P. Steinbach wrote:
    > > * anderberg:
    > >> Consider the following code,
    > >>
    > >> #include <iostream>
    > >>
    > >> struct Functor {
    > >> void operator()(void) { std::cout << "Functor" << std::endl; }

    > >
    > > 'void' as formal argument list is C-ism; don't.

    >
    > Like to be explicit.


    void func();
    void func(void);

    In C these two mean different things. In C++ they are exactly
    equivalent. In C++, void func() *is* explicit. It means that func takes
    no parameters.

    C++ programmers do not expect to see a redundant 'void' in the formal
    parameter list any more than they expect to see a redundant 'auto' in
    front of every local variable declararion.

    Gavin Deane
    , Dec 7, 2005
    #5
  6. anderberg

    Marcus Kwok Guest

    anderberg <> wrote:
    > On 2005-12-07, Alf P. Steinbach wrote:
    >> * anderberg:
    >>> Why isn't operator() called for the temporary object that's created?

    >>
    >> Why should it?

    >
    > Functor a;
    > a();
    >
    > I figured that Functor() would translate to something similar to
    > the above. I guess I was wrong. But the question remains - why
    > doesn't it?


    Functor() creates a temporary Functor object and default initializes it.
    As others have suggested, Functor()() does what you want. To
    illustrate, add a default constructor:

    #include <iostream>

    struct Functor {
    void operator()() { std::cout << "()\n"; }
    Functor() { std::cout << "Functor\n"; }
    };

    int main()
    {
    Functor();
    Functor()();
    }

    /*
    Output:

    Functor
    Functor
    ()

    */

    >> Try Functor()().

    >
    > Thanks!


    --
    Marcus Kwok
    Marcus Kwok, Dec 7, 2005
    #6
  7. anderberg

    Rolf Magnus Guest

    anderberg wrote:

    >>> Why isn't operator() called for the temporary object that's created?

    >>
    >> Why should it?

    >
    > Functor a;
    > a();
    >
    > I figured that Functor() would translate to something similar to
    > the above. I guess I was wrong. But the question remains - why
    > doesn't it?


    If you rewrite your class to:

    struct Functor {};

    Would you expect the compiler to complain about a missing operator() in the
    line saying:

    Functor();

    ? If not, why do you expect the operator() to be called?
    Rolf Magnus, Dec 7, 2005
    #7
  8. anderberg

    anderberg Guest

    On 2005-12-07, wrote:
    >
    > void func();
    > void func(void);
    >
    > In C these two mean different things. In C++ they are exactly
    > equivalent. In C++, void func() *is* explicit. It means that func takes
    > no parameters.
    >
    > C++ programmers do not expect to see a redundant 'void' in the formal
    > parameter list any more than they expect to see a redundant 'auto' in
    > front of every local variable declararion.


    Point taken. I'll make a habit not to use it, then. Last six years
    of embedded C has obviously left a legacy.

    --
    anderberg: People are just mutations. Some worse than others.
    anderberg, Dec 7, 2005
    #8
  9. anderberg

    Mike Smith Guest

    anderberg wrote:
    > On 2005-12-07, wrote:
    >
    >>void func();
    >>void func(void);
    >>
    >>In C these two mean different things. In C++ they are exactly
    >>equivalent. In C++, void func() *is* explicit. It means that func takes
    >>no parameters.
    >>
    >>C++ programmers do not expect to see a redundant 'void' in the formal
    >>parameter list any more than they expect to see a redundant 'auto' in
    >>front of every local variable declararion.

    >
    >
    > Point taken. I'll make a habit not to use it, then. Last six years
    > of embedded C has obviously left a legacy.


    Not to mention that many of us still program in both languages, and
    while *yes, we know* that they're not the same language, in practice
    things tend to run together.

    --
    Mike Smith
    Mike Smith, Dec 7, 2005
    #9
  10. anderberg

    Default User Guest

    Alf P. Steinbach wrote:

    > * anderberg:


    > > {
    > > Functor();
    > > return 0;

    >
    > Not necessary in 'main', because 'main' is a special function.


    While techinically true, it's not any kind of error to include the
    return. I always include it. If nothing else, it signals to the
    maintainer that the original programmer didn't just forget about the
    return, that 0 was indeed what was meant.

    Some compilers will flag it with a warning.

    Many common coding standards mandate the use of explict returns in
    main().



    Brian

    --
    Please quote enough of the previous message for context. To do so from
    Google, click "show options" and use the Reply shown in the expanded
    header.
    Default User, Dec 7, 2005
    #10
  11. anderberg

    anderberg Guest

    On 2005-12-07, Default User wrote:
    > Alf P. Steinbach wrote:
    >
    >> * anderberg:

    >
    >> > {
    >> > Functor();
    >> > return 0;

    >>
    >> Not necessary in 'main', because 'main' is a special function.

    >
    > While techinically true, it's not any kind of error to include the
    > return. I always include it. If nothing else, it signals to the
    > maintainer that the original programmer didn't just forget about the
    > return, that 0 was indeed what was meant.
    >
    > Some compilers will flag it with a warning.
    >
    > Many common coding standards mandate the use of explict returns in
    > main().


    http://www.research.att.com/~bs/bs_faq2.html#void-main says

    "Note also that neither ISO C++ nor C99 allows you to leave
    the type out of a declaration. That is, in contrast to C89
    and ARM C++ ,"int" is not assumed where a type is missing in a
    declaration. Consequently:

    #include<iostream>

    main() { /* ... */ }

    is an error because the return type of main() is missing."

    --
    anderberg: People are just mutations. Some worse than others.
    anderberg, Dec 16, 2005
    #11
  12. anderberg

    Rolf Magnus Guest

    anderberg wrote:

    >>> * anderberg:

    >>
    >>> > {
    >>> > Functor();
    >>> > return 0;
    >>>
    >>> Not necessary in 'main', because 'main' is a special function.

    >>
    >> While techinically true, it's not any kind of error to include the
    >> return. I always include it. If nothing else, it signals to the
    >> maintainer that the original programmer didn't just forget about the
    >> return, that 0 was indeed what was meant.
    >>
    >> Some compilers will flag it with a warning.
    >>
    >> Many common coding standards mandate the use of explict returns in
    >> main().

    >
    > http://www.research.att.com/~bs/bs_faq2.html#void-main says
    >
    > "Note also that neither ISO C++ nor C99 allows you to leave
    > the type out of a declaration. That is, in contrast to C89
    > and ARM C++ ,"int" is not assumed where a type is missing in a
    > declaration. Consequently:
    >
    > #include<iostream>
    >
    > main() { /* ... */ }
    >
    > is an error because the return type of main() is missing."


    Yes, however, that's only talking about the return _type_, not about the
    explicit return statement.
    I.e.:

    int main() { }

    is not an error, even though a return is missing.
    Rolf Magnus, Dec 16, 2005
    #12
  13. anderberg

    Default User Guest

    anderberg wrote:

    > On 2005-12-07, Default User wrote:
    > > Alf P. Steinbach wrote:
    > >
    > >> * anderberg:

    > >
    > >> > {
    > >> > Functor();
    > >> > return 0;
    > >>
    > >> Not necessary in 'main', because 'main' is a special function.

    > >
    > > While techinically true, it's not any kind of error to include the
    > > return. I always include it. If nothing else, it signals to the
    > > maintainer that the original programmer didn't just forget about the
    > > return, that 0 was indeed what was meant.
    > >
    > > Some compilers will flag it with a warning.
    > >
    > > Many common coding standards mandate the use of explict returns in
    > > main().

    >
    > http://www.research.att.com/~bs/bs_faq2.html#void-main says
    >
    > "Note also that neither ISO C++ nor C99 allows you to leave
    > the type out of a declaration. That is, in contrast to C89
    > and ARM C++ ,"int" is not assumed where a type is missing in a
    > declaration. Consequently:
    >
    > #include<iostream>
    >
    > main() { /* ... */ }
    >
    > is an error because the return type of main() is missing."



    You are confused about what we were discussing. We were going over this
    programming idiom:

    int main()
    {
    // do stuff
    }

    Versus:

    int main()
    {
    // do stuff

    return 0;
    }


    Alf points out, correctly, that the return statement is not required in
    main() because the standard mandates that falling off the end for that
    function (alone) is the equivalent to returning 0. I prefer to have
    explicit returns anyway.


    Brian
    Default User, Dec 16, 2005
    #13
    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. bigbinc
    Replies:
    3
    Views:
    385
    Michael Borgwardt
    Nov 18, 2003
  2. Brian
    Replies:
    2
    Views:
    324
    Brian
    Oct 31, 2003
  3. Simon Elliott

    Inheritance of objects within objects

    Simon Elliott, Dec 10, 2004, in forum: C++
    Replies:
    2
    Views:
    321
    Simon Elliott
    Dec 10, 2004
  4. Protoman
    Replies:
    11
    Views:
    517
  5. 7stud
    Replies:
    11
    Views:
    662
    Dennis Lee Bieber
    Mar 20, 2007
Loading...

Share This Page