好吧,我是操作员重载的新手,我发现了这个问题。我不想记录自己,而是问你:D
关键是,我知道如何进行简单的运算符重载,但我遇到了堆栈运算符的问题。我将尝试举一个相对简单的例子:
struct dxfdat
{
int a;
string b;
/* here is the question */
}
/* use: */
dxfdat example;
example << "lalala" << 483 << "puff" << 1029 << endl;
"lalala" << 483 << "puff" << 1029 << endl
应存储在b
。
dxfdat& operator<< (T a)
这样的事情可以使用一个参数(example << 7)
,但我希望它以'cout
'方式工作。
抱歉这么懒。
编辑:
真实的东西......好吧,它有点棘手......实际上,b不是字符串,而是其他对象的向量,而example << "lalala" << 483 << "puff" << 1029 << endl
应该只创建一个对象。 / p>
这就是我正在尝试(翻译)的内容,虽然我不知道如何告诉它何时创建对象(因为它从左到右,不是吗?):
struct dxfDato
{
dxfDato(int c = 0, string v = 0, int t = 0) { cod = c; val= v; ty = t; }
int ty;
int cod;
string val;
};
struct dxfItem
{
int cl;
string val;
vector<dxfDato> dats;
vector<dxfItem> sons;
template <class T>
dxfItem &operator<<(const T &t)
{
dxfDato dd;
std::stringstream ss;
ss << t;
val = ss;
dats.push_back(dd); // this way, it creates a lot of objects
return d;
}
};
dxfItem headers;
headers << "lalala" << 54789 << "sdfa" << 483 << endl;
// this should create *just one object* in dats vector,
// and put everything on string val
感谢您的一切,
注意:我必须提取并翻译很多东西才能把它放在这里,所以我没有检查代码是否有愚蠢的错误。
(很抱歉扩大这个问题,如果我误用了stackoverflow的问题系统,请告诉我)
答案 0 :(得分:7)
诀窍是从operator <<
返回对你自己的引用 - 这样,操作符可以“堆叠”。
class me {
me& operator<<(int t) {...; return *this;}
};
me m;
m << 4 << 5 << 6;
只需为你想要支持的所有类型的移位操作符重载(或者如果你能负担危险就把它变成模板)!
答案 1 :(得分:2)
template <typename T>
dxfdata & operator <<( dxfdata & d, const T & t ) {
std::ostringstream os;
os << t;
d.b += os.str();
return d;
}
答案 2 :(得分:1)
这很容易,不要惊慌:)
您已经很好地认识到了这个问题:它与std::cout
- std::endl
工作非常相似。
你可以这样做,但如果你不介意我会重命名这些类型。
struct EndMarker {};
extern const EndMarker end; // To be defined in a .cpp
class Data
{
public:
Data(): m_data(1, "") {}
// Usual operator
template <class T>
Data& operator<<(const T& input)
{
std::ostringstream aStream;
aStream << input;
m_data.back() += aStream.str();
};
// End of object
Data& operator<<(EndMarker) { m_data.push_back(""); }
private:
std::vector<std::string> m_data;
}; // class Data
它的工作原理是默认添加到当前的最后一个元素,并在结尾处推送一个空元素。
让我们看一个例子:
Data data;
data << 1 << "bla" << 2 << end << 3 << "foo" << end;
// data.m_data now is
// ["1bla2", "3foo", ""]
另一个解决方案是保持一个标志(布尔值)来存储end
是否已经流式传输,如果有,则在下次插入时创建一个新元素(并删除标志)。
在插入方面还有一些工作要做,但你没有空元素......你的电话。