C++运算符重载示例

发布于 2024-08-19 21:50:33 字数 1613 浏览 2 评论 0原文

好吧,我是运算符重载的新手,我发现了这个问题。我不想自己记录,而是更愿意问你:D

重点是,我知道如何进行简单的运算符重载,但我面临着堆叠运算符的问题。我将尝试举一个相对简单的示例:

struct dxfdat
{
 int a;
 string b;

 /* here is the question */
}

/* use: */
dxfdat example;

example << "lalala" << 483 << "puff" << 1029 << endl;

"lalala" <<第483章“噗”<<第1029章endl应存储在b中。

dxfdat&运算符<< (T a) 以及类似的东西可以使用一个参数(示例 << 7),但我希望它可以在 'cout 中工作' 时尚。

抱歉这么懒。

编辑:

真正的事情...好吧,这有点棘手...实际上, b 不是一个字符串,而是其他对象的向量,并且 example << “啦啦啦”<<第483章“噗”<<第1029章endl 应该只创建一个对象。

这就是我正在尝试的(翻译),尽管我不知道如何告诉它何时创建对象(因为它从左到右,不是吗?):

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 的问题系统)

Well, I'm new to operator overloading, and I found this problem. Instead of documenting myself, I prefer to ask you :D

The point is, I know how to do simple operator overloading, but I'm facing problems with stacking operators. I'll try to put a relatively simple example:

struct dxfdat
{
 int a;
 string b;

 /* here is the question */
}

/* use: */
dxfdat example;

example << "lalala" << 483 << "puff" << 1029 << endl;

"lalala" << 483 << "puff" << 1029 << endl shall be stored in b.

dxfdat& operator<< (T a) and things like that work with one parameter (example << 7), but I would like it to work in a 'cout' fashion.

Sorry to be so lazy.

EDIT:

The real thing... Ok, it is a little bit trickier... actually, b isn't a string, but a vector of other objects, and example << "lalala" << 483 << "puff" << 1029 << endl should just create just one object.

This is what I'm trying (translated), though I have no clue on how to tell it when to create the object (as it goes from left to right, doesn't it?):

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

Thanks for everything,

Note: I had to extract and translate a lot of things to put it here, so I didn't check the code for stupid errors.

(Sorry for expanding the question that much, please tell me if I'm misusing stackoverflow's question system)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

旧梦荧光笔 2024-08-26 21:50:33

诀窍是从 operator << 返回对您自己的引用 - 这样,运算符就可以“堆叠”。

class me {

    me& operator<<(int t) {...; return *this;}
};

me m;
m << 4 << 5 << 6;

只需为您希望支持的所有类型重载移位运算符(或者如果您能承受危险,请将其作为模板)!

The trick is to return a reference to youself from operator << - this way, the operator can be 'stacked'.

class me {

    me& operator<<(int t) {...; return *this;}
};

me m;
m << 4 << 5 << 6;

Just overload the shift operator for all types you wish to support (or make it a template if you can afford the danger)!

画离情绘悲伤 2024-08-26 21:50:33
template <typename T>
dxfdata & operator <<( dxfdata & d, const T & t ) {
   std::ostringstream os;
   os << t;
   d.b += os.str();
   return d;
}
template <typename T>
dxfdata & operator <<( dxfdata & d, const T & t ) {
   std::ostringstream os;
   os << t;
   d.b += os.str();
   return d;
}
GRAY°灰色天空 2024-08-26 21:50:33

这很简单,不要惊慌:)

您已经很好地认识到了这个问题:它与 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 是否已流式传输,如果已流式传输,则在下一次插入时创建一个新元素(并且擦除标志)。

插入方面需要做更多的工作,但是你没有空元素......你的电话。

It's quite easy, don't panic :)

You have recognized the problem well: it's very similar to the std::cout - std::endl work.

You could do like such, though I'll rename the types, if you don't mind.

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

It works by adding to the current last element by default, and pushing an empty element at the end.

Let's see an example:

Data data;
data << 1 << "bla" << 2 << end << 3 << "foo" << end;

// data.m_data now is
// ["1bla2", "3foo", ""]

The other solution would be to keep a flag (boolean) to store if a end has been streamed or not, and if it has, creating a new element on the next insertion (and erasing the flag).

It a bit more work on insertion, but you don't have the empty element... your call.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文