I\'m trying to change some of my functions foo()
into operator<<()
, simply for the sake of getting some \"half C/half C++\" code to look more
The language is doing what you are asking it to do.
With associativity, the following are equivalent (<<
and >>
are left-to-right associative):
a << 1 << 2
(a << 1) << 2
The call a << 1
calls your user-defined operator, which in turn returns a size_t
. That's why the types for next call are the following: size_t << int
(which is a simple bitwise shift).
You need to use expression templates. The idea is the following (live example here):
template
struct stream_op
{
};
template
stream_op operator<<(stream_op a, B b)
{
// Do stuff
}
So, the following occur (with a
as a stream_op<>
):
a << 1 << 2
------
|
v
-------------------------------------------
stream_op operator<<(stream_op<>, int) << 2
-------------- ---
| |
| +---------------------------+
v v
-------------- ---
stream_op << int
-------------- ---
| |
| +---------------------------+
+----------------------------+ |
v v
-------------- ---
stream_op operator<<(stream_op, int)
------------------
|
v
------------------
stream_op // <- Expected result
Then you just have to put a method to convert stream_op
to int (or to whatever you want).
A note on performances: with these expression templates, a part of the data is encoded in the type, so normally it should be as fast as a direct call to foo(...)
.