How I'd deal with this
Okay, so you have this:
std::stringstream ss; ss << "lives:" << this->Lives;
Text->RenderText(ss.str(), font, x, y, scale,color);
Now if you really want to do it in a single line, why not put the string generation into a single function call, something specific like
std::string life_text(int lifecount){
std::stringstream ss;
ss<<"lives:"<<lifecount;
return ss.str();
}
So you can call render like this:
Text->render(life_text(lives), x, y, scale,color);
What you're looking for
First, before I answer the question that you asked, the <<
operator does not imply method chaining. At least not in vanilla C++, in fact, I don't think it's used anywhere like that in c++.
The stream objects aren't really chaining a method, but calling something like
template<typename T> std::stringstream& operator<<(std::stringstream& rightside,T leftside){
rightside.append(leftside);
return rightside;
}
So what happens at each step of that is something like:
stringstream r;
r<<"lives:";
r<<this->lives;
What you are asking for isn't really all that simple. You would need to change the rendertext function to return a new sort of object that you can pass arguments to. That's hard.
Second of all, that would mean that your evaluation order would make this somewhat more challenging. There are ways around that, but I don't know if this is a situation where a simple convenience function like above wouldn't be better.
If you're dead set on doing this that way, then you might have to do something that is really potentially very problematic. You'd have to make the object call the actual render function(which I assume you probably have from some framework) at its disposal.
Fine, but now you've required adding some scope that might matter if you need this done in a specific order. It would look, potentially, like this:
{
Text->render(x,y,scale,color)<<"lives:"<<this->Lives;
}
To my eyes, that looks frustrating.
I'll answer any questions you might have relating to my answer, if you'd like, but, at least to my eyes, your original goal seems like you're barking up the wrong tree with how you'd like to do this.
Something approaching a solution in the manner you wanted
template<std::function<typename ReturnType(std::string&,typename Ts...)> Func>
class caller{
std::stringstream r;
Ts... arguments;
Func storedFunction;
public:
caller(Func x,typename Ts...):storedFunction(x){
arguments=Ts;
}
~caller(){
Func(r.str(),...Ts);
}
friend template<typename S,typename P> caller<S>& operator<<(caller<S>&,T value);
};
template<typename S,typename P> caller<S>& operator<<(caller<S>& c, T value){
c.r<<value;
}
caller a_suitable_name(std::bind(&Text::Render,&Text),_those_other_arguments);
caller<<"lives:"<
This isn't likely to work in its present form, but I don't have time to finish the definition.