Jump to content
  • Advertisement
Sign in to follow this  
DevFred

printing via functor

This topic is 3657 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I wrote the following functor:
class functor
{
    int i;
public:
    functor(int i) : i(i) {}
    ostream& operator()(ostream& os) const
    {
        // do something sensible with i
        // ...

        return os;
    }
};
Then I tried to print it:
int main()
{
    cout << functor(10);
}
Which didn't work because operator << wasn't overloaded suitably. So I overloaded it myself:
ostream& operator<<(ostream& os, const functor& fun)
{
    return fun(os);
}
Then I thought "Wouldn't it be handy if I could print EVERY functor?" and replaced the overloaded operator by the following template:
template<typename F>
ostream& operator<<(ostream& os, const F& f)
{
    return f(os);
}
Now my question is: does this template exist somewhere predeclared, so I don't have to declare it myself? It makes a lot of sense, doesn't it? ;)

Share this post


Link to post
Share on other sites
Advertisement
I don't think so. (It doesn't print every functor anyway, only those that take and return an ostream&).

It seems that it would make more sense to output the return value of functor calls?


#include <iostream>
using namespace std;
class functor
{
int i;
public:
functor(int i) : i(i) {}
int operator()() const
{
// do something sensible with i
// ...

return i;
}
};

int main()
{
functor f(10);
cout << f();
}

Share this post


Link to post
Share on other sites
Don't mix concepts like this.

Operator<< has well known function. That's how printing is done.

For functors, operator() is equivalent to function call that the functor represents. Anything else, and it becomes confusing.

Is there a reason you need to change function call into ostream operator?

Quote:
// do something sensible with i


Whatever you do with i is irrelevant, since it has no side-effects. You do respect the const, right?


Just because language concepts allow you to do something, doesn't mean it's a good idea.

And no, such overload does not exist since it's not sensible. For most things, it would break existing libraries.

Share this post


Link to post
Share on other sites
Quote:
Original post by Antheus
Is there a reason you need to change function call into ostream operator?

It's a homework assignment where I have to be able to write
cout << binary(10);

Normally I would just overload operator<<(ostream&, const binary&) and make that a friend of binary, but I am required to use the member operator()(ostream&).

Share this post


Link to post
Share on other sites
This is actually a very interesting facet of the standard library. Not as it applies to your situation (just provide a cast operator), but as it applies to manipulators.

You see, the development of the iostreams library far predated the development of C++ templates, and therefore the C++ functor. Functors are ideal for partial application (at least, more ideal than anything else the language offers), so they're ideal for manipulators, which are partially applied with parameters, and then fully applied on the iostream in question. Only.. the standard doesn't use functors like that. Oh, it doesn't prohibit their use, and in fact templates are usually used to implement manipulators, but the standard simply specifies that manipulators which take arguments must return "some type" (represented as smanip)which can then be used on the right hand side of the insertion operator. The first version of C++ which included manipulators, in fact, used a preprocessor macro to simulate something very much like templates for this purpose. Later versions moved to real templates for this purpose, but the ambiguity is still built into the standard, making it considerably more annoying to extend and interoperate with the iostreams library.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!