目前我有一个方法如下:
std::stringstream ss; ss << "lives:" << this->Lives;
Text->RenderText(ss.str(), font, x, y, scale,color);
现在这对我来说似乎很混乱,我想把它减少到一行。 但我似乎无法想出一种干净利落的方法。
我想过使用varidic函数,但这限制了我一种类型,我必须指定参数的数量。
此外,虽然使用了std :: initializer_list或varidic模板,但它看起来并不好看。
在此解决方案中:Here Georg Fritzsche提供的答案显示了一个可行的解决方案:
helper() << a << b << c;
但实际执行它我不确定。
类似于:
Text->render(font, x, y, scale,color) << "lives:" << this->Lives;
会很好,但在方法中我不确定如何定义它。
我无法返回一个stringstream对象,因为我无法在返回后访问它。
那么如何用链接&lt;&lt;这样的方法呢?工作?
答案 0 :(得分:3)
返回一个临时对象,它累积字符串的所有部分,然后在语句结束时自动销毁它,让它在析构函数中呈现内容。
#include <utility>
#include <string>
#include <sstream>
#include <iostream>
using namespace std;
class Renderer {
stringstream sstream;
float x;
float y;
public:
Renderer(float x, float y) : x(x), y(y){}
template<class T>
Renderer && operator<<(T&& t) {
sstream << std::forward<T>(t);
return std::move(*this);
};
~Renderer() {
// your real code replaces the line below..
cout << sstream.str() << endl;
}
};
Renderer render(float x, float y) {
return Renderer(x, y);
}
int main() {
int i = 5;
render() << "foo" << i;
}
答案 1 :(得分:-1)
好的,你有这个:
std::stringstream ss; ss << "lives:" << this->Lives;
Text->RenderText(ss.str(), font, x, y, scale,color);
现在,如果您真的想在一行中完成,为什么不将字符串生成放入单个函数调用中,具体如
std::string life_text(int lifecount){
std::stringstream ss;
ss<<"lives:"<<lifecount;
return ss.str();
}
所以你可以像这样调用渲染:
Text->render(life_text(lives), x, y, scale,color);
首先,在我回答您提出的问题之前,<<
运算符并不意味着方法链接。至少在香草C ++中没有,事实上,我不认为它在c ++中的任何地方使用过。
流对象并不是真正链接一个方法,而是调用
之类的东西template<typename T> std::stringstream& operator<<(std::stringstream& rightside,T leftside){
rightside.append(leftside);
return rightside;
}
那么在每一步中发生的事情都是这样的:
stringstream r;
r<<"lives:";
r<<this->lives;
你所要求的并非如此简单。您需要更改rendertext函数以返回可以传递参数的新类型的对象。这很难。
其次,这意味着您的评估订单会使这更具挑战性。有办法解决这个问题,但我不知道这种情况是否会像上面那样简单的便利功能不会更好。
如果您已经这样做了,那么您可能不得不做一些非常有问题的事情。您必须使对象调用实际的渲染函数(我假设您可能已经从某个框架中获得)。
很好,但是现在您需要添加一些可能很重要的范围,如果您需要按特定顺序完成此操作。看起来可能是这样的:
{
Text->render(x,y,scale,color)<<"lives:"<<this->Lives;
}
在我看来,这看起来很令人沮丧。
如果您愿意,我会回答您有关我的答案的任何问题,但至少在我看来,您原来的目标似乎是在咆哮着错误的树你是怎么想这样做的。
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(&amp; Text :: Render,&amp; Text),_ those_other_arguments); 呼叫者LT;&LT;&#34;住:&#34;&LT;
这不可能以目前的形式发挥作用,但我没有时间完成定义。