Re: Isn't function resolution consistent?
Paul Bibbings wrote:
DeMarcus <use_my_alias_here@hotmail.com> writes:
Here's a relevant follow-up question. When C++0x comes, shall we
change all the print operators from
std::ostream& operator<<( std::ostream& s, const SomeClass& sc );
to
std::ostream& operator<<( std::ostream&& s, const SomeClass& sc );
Did you perhaps intend this second to be:
std::ostream& operator<<(std::ostream& s, const SomeClass&& sc ); ?
No, I meant exactly what I wrote this time. ;)
I want to do this:
fnc( const A& a );
int main()
{
B b;
fnc( A() << b );
}
....and still have my non-member function invoked. It works if I do this:
A& operator<<( A&& a, const B& b );
The first parameter will need to remain std::ostream&, or otherwise you
are attempting to create an rvalue-reference temporary to the stream
object which is surely not what you intend.
I just intend to call the non-member function for both
A() << b;
and
a << b;
In
A& operator<<( A&& a, const B& b );
will A&& do something with what's input there? I've read somewhere that
rvalue references will be used for move semantics. Would anything input
here be moved?
since the rvalue reference will catch both
a << b;
and
A() << b;
Or will there be other complications doing that change?
I'm a little confused by this, since your usage:
a << b; and A() << b;
refers to your own overloaded op<<'s, which don't match the signature
of the `conventional' op<< that you give the declaration for above. You
appear to be mixing the two in your question.
I'm doing my own kind of stream called A. But I want it to be as similar
to std::ostream as possible.
As to the first (though I appreciate this may not be what you are
asking), there is no need to change the parameter types to rvalue
references, as the following example illustrates:
11:21:27 Paul Bibbings@JIJOU
/cygdrive/d/CPPProjects/CLCPP/consistent_resolution $cat cpp0x_ex.cpp
// file: cpp0x_ex.cpp
#include <iostream>
class SomeClass { };
std::ostream& operator<<(std::ostream& s, const SomeClass& sc)
{
return s << "op<<";
}
int main()
{
SomeClass sc;
std::cout << sc; // lvalue
std::cout << SomeClass(); // rvalue
std::cout << std::move(sc); // rvalue reference
}
11:21:36 Paul Bibbings@JIJOU
/cygdrive/d/CPPProjects/CLCPP/consistent_resolution
$i686-pc-cygwin-gcc-4.5.0 -std=c++0x -c cpp0x_ex.cpp
11:22:04 Paul Bibbings@JIJOU
/cygdrive/d/CPPProjects/CLCPP/consistent_resolution
$i686-pc-cygwin-g++-4.5.0 -o cpp0x_ex cpp0x_ex.o
11:27:07 Paul Bibbings@JIJOU
/cygdrive/d/CPPProjects/CLCPP/consistent_resolution $./cpp0x_ex
op<<op<<op<<
The key here (in a sense) is the const on the second parameter, which
evidently permits all these combinations.
Yes, but in my case the ostream may be an rvalue, like this.
void print( const std::ostream& s )
{
std::cout << s.rdbuf() << std::endl;
}
int main()
{
SomeClass sc;
print( std::stringstream() << sc );
}
therefore I need to define the operator like this
std::ostream& operator<<( std::ostream&& s, const SomeClass& sc );
or will the rvalue reference do something bad with the stream if I use a
classic output like the following?
std::cout << SomeClass();