Hi, I have defined a global overloaded operator<<. I want to use this overloaded operator in std::for_each(), but it must be properly deduced since there are many global overloads for this operator. For example: class Stream { // This is an abstract class (cannot instantiate) }; Stream& operator<< ( Stream& stream, char data ) { stream.write( data ); return stream; } Stream& operator<< ( Stream& stream, std::vector<char>& buffer ) { using namespace boost::lambda; std::for_each( buffer.begin(), buffer.end(), var( stream ) << _1 ); // This lambda should simply be binding to the overloaded operator<< above, right? return stream; } When I compile this, MSVC9 tells me: 1>c:\program files\microsoft visual studio 9.0\vc\include\algorithm(29) : error C2064: term does not evaluate to a function taking 1 arguments 1> class does not define an 'operator()' or a user defined conversion operator to a pointer-to-function or reference-to-function that takes appropriate number of arguments What am I doing wrong? Do I need to be using boost bind instead? If so, how can I use boost.bind to map a global operator? Will it correctly deduce which overload to use?
AMDG Robert Dailey wrote:
Hi,
I have defined a global overloaded operator<<. I want to use this overloaded operator in std::for_each(), but it must be properly deduced since there are many global overloads for this operator. For example: <snip>
What am I doing wrong? Do I need to be using boost bind instead? If so, how can I use boost.bind to map a global operator? Will it correctly deduce which overload to use?
Unfortunately, Boost.Lambda does not handle user defined operators
automatically.
If you don't do this Lambda will try to return a Stream by value which
apparently
triggers SFINAE when Stream is abstract.
#include <iostream>
#include
On Fri, Mar 21, 2008 at 10:16 PM, Steven Watanabe
AMDG
Robert Dailey wrote:
Hi,
I have defined a global overloaded operator<<. I want to use this overloaded operator in std::for_each(), but it must be properly deduced since there are many global overloads for this operator. For example: <snip>
What am I doing wrong? Do I need to be using boost bind instead? If so, how can I use boost.bind to map a global operator? Will it correctly deduce which overload to use?
Unfortunately, Boost.Lambda does not handle user defined operators automatically. If you don't do this Lambda will try to return a Stream by value which apparently triggers SFINAE when Stream is abstract.
#include <iostream> #include
#include <vector> #include <algorithm> class Stream { public: virtual void abstract() = 0; // This is an abstract class (cannot instantiate) void write(char ch) { std::cout << ch; } };
class MyStream : public Stream { void abstract() {} };
Stream& operator<< ( Stream& stream, char data ) { stream.write( data ); return stream; }
namespace boost { namespace lambda {
template<> struct plain_return_type_2
, Stream, char> { typedef Stream& type; }; } }
Stream& operator<< ( Stream& stream, std::vector<char>& buffer ) { using namespace boost::lambda; std::for_each( buffer.begin(), buffer.end(), var( stream ) << _1 ); return stream; }
int main() { MyStream s; std::string str("test1"); std::vector<char> b(str.begin(), str.end()); s << b; }
Will the plain_return_type_2 specialization also work for classes derived from Stream? Or do I need to specialize that structure for each and every single class, regardless of inheritance? Thanks.
AMDG Robert Dailey wrote:
Will the plain_return_type_2 specialization also work for classes derived from Stream? Or do I need to specialize that structure for each and every single class, regardless of inheritance? Thanks.
Yes, you would need to specialize for every derived class. The other alternative is to use an explicit return type. http://www.boost.org/doc/html/lambda/le_in_details.html#lambda.overriding_de... In Christ, Steven Watanabe
On Fri, Mar 21, 2008 at 10:52 PM, Steven Watanabe
AMDG
Robert Dailey wrote:
Will the plain_return_type_2 specialization also work for classes derived from Stream? Or do I need to specialize that structure for each and every single class, regardless of inheritance? Thanks.
Yes, you would need to specialize for every derived class. The other alternative is to use an explicit return type.
http://www.boost.org/doc/html/lambda/le_in_details.html#lambda.overriding_de...
How about Boost.Bind? Could I use it to bind my operator? I would also expect it to choose the correct overload of the stream operator depending on the type of _1. I have not used Bind like this before, so I'm not sure if it is capable. If all else fails you've given me 2 alternatives concerning Boost.Lambda, so I could always go with that. Thanks for all the help.
AMDG Robert Dailey wrote:
How about Boost.Bind? Could I use it to bind my operator? I would also expect it to choose the correct overload of the stream operator depending on the type of _1. I have not used Bind like this before, so I'm not sure if it is capable. If all else fails you've given me 2 alternatives concerning Boost.Lambda, so I could always go with that.
To use bind you would have to wrap the stream operator in a function object. struct stream_operator { typedef Stream& result_type; Stream& operator()(Stream& stream, char ch) const { return(stream << ch); } }; ... boost::bind(stream_operator(), stream, _1); In Christ, Steven Watanabe
participants (2)
-
Robert Dailey
-
Steven Watanabe