【问题标题】:Operator << in a user defined method用户定义方法中的运算符 <<
【发布时间】:2015-06-25 08:52:40
【问题描述】:

我试图编写一个方法,该方法将使用&gt;&gt; 运算符作为类似于std::cin 的参数,但我不知道如何。是否有可能创建这种将这种流作为参数的方法,将其正确转换(例如将所有整数转换为字符串等),然后保存到 std::string 变量?

这是我想如何运行该函数的示例:

int i = 0;
myMethod << "some text" << i << "moar text";

在该方法中,我想获取这些参数并存储在一个字符串中。

编辑

我将尝试准确解释此应用程序的用途:我正在尝试创建一个 Clogger 单例类,该类将用于将日志保存到文件中。通过这种结构,我可以从代码中的任何位置调用*CLogger::instance() &lt;&lt; "log stuff";,这没关系。感谢这个主题的答案,我来到了这个。问题是我使用的每个operator&lt;&lt;,都会调用该对象。因此,如果我执行 *CLogger::instance()

template<typename T>
    CLogger& operator<<(const T& t)
    {
        ...

        return *this;
    }

这对我不利,因为我打算在每个日志行之前和之后添加一些文本。例如,我总是想在之前和之后添加时间std::endl。按照我给出的例子而不是得到:

[00:00] log stuff more stuff even more

我会得到:

[00:00] log stuff 
[00:00]  more stuff 
[00:00]  even more

所以我尝试通过改变这样的方法来消除这种行为:

template<typename T>
    CLogger& operator<<(const T& t)
    {
        ostringstream stream;
        stream << t;
        m_catString += stream.str();

        if (stream.str() == "\n")
        {
            push_back(m_catString);
            m_catString.clear();
        }

        return *this;
    }

这样,如果我在末尾添加"\n",程序就会知道何时推送新的日志行。它几乎没问题,因为我敢打赌我会忘记添加这个。有没有更巧妙的办法?

【问题讨论】:

  • 有数以千计的教程和问题,每一本介绍性的 c++ 书籍都涵盖了它。尝试阅读一本,如果遇到困难,请返回。
  • 同时修正你的标题。您那里的运算符有误。
  • @juanchopanza 感谢您的提示,我已修复它。问题是这个主题不是那么基本,我发现很难找到任何直接的信息。此外,C++ 书籍并没有说太多。
  • 您可能应该在询问之前使用搜索引擎的强大功能。 :)
  • @ŁukaszPrzeniosło 看看我的编辑

标签: c++ operators


【解决方案1】:

您不能将参数传递给使用&lt;&lt; 的方法,您需要一个对象。

类似这样的:

struct A
{
    template<typename T>
    A& operator<<(const T& t)
    {
        std::ostringstream stream;
        stream << t;
        data += stream.str();
        return *this;
    }
    std::string data;
};

// ...

A a;
a << "Hello " << 34 << " World";
std::cout << a.data;

关于您的更新:

最明显的是实现CLogger中的操作符,去掉Pusher类;那会让你写*CLogger::instance() &lt;&lt; "sample text" &lt;&lt; 10;

如果由于某种原因无法做到这一点(您提供的信息是零碎的,所以很难说),您可以声明 Pusher 为朋友并使用与其他任何地方相同的方法:

struct Pusher
{
    template<typename T>
    Pusher& operator<<(const T& t)
    {
        std::ostringstream stream;
        stream << t;
        CLogger::instance()->push_back(stream.str());
        return *this;
    }

};

【讨论】:

  • 我现在非常接近,我已经根据您的答案更新了我的代码,但我会提出后续答案。
  • 请告诉我您还需要什么信息,我会提供。我真的很想像您指定的那样给接线员打电话。这正是我需要的,但就像你说的我不能那样运行它:error: invalid operands of types ‘CLogger*’ and ‘const char [12]’ to binary ‘operator&lt;&lt;’
  • @ŁukaszPrzeniosło 你忘了*
  • 你说得对,正要写这个。谢谢你。我还必须从 push_back 参数中删除引用。
  • 但是,我刚刚注意到一个问题。我可以打电话给*CLogger::instance() &lt;&lt; 10;,但我不能打电话给*CLogger::instance() &lt;&lt; 10 &lt;&lt; "test",因为我收到一个错误error: call of overloaded ‘to_string(const char [5])’ is ambiguous...知道吗?所以现在我不能使用带有 to_string 的字符串,也不能使用没有它的整数。
【解决方案2】:

我知道的唯一方法是创建一个类class Method,然后重载operator&lt;&lt;operators overloading

template<class T>
Method &operator<<(const T &x)
{
    // Do whatever you like
    return *this;
}

然后你可以像这样使用它:

Method myMethod;
myMethod << ... ;

您可以查看this question 关于创建cout-like 类 顺便说一句,std::cin 和 std::cout 不是函数

编辑

class CLogger
{
  ...

  template<typename T>
  CLogger& operator<<(const T& t)
  {
     push_back(std::to_string(t));
     return *this;
  }


};

你不必创建一个类 Pusher,只需在你的第一个类中重载运算符,现在你可以将它与你的对象一起使用:

myCLogger &lt;&lt; t; // this would call the function push back

【讨论】:

  • 感谢您的编辑。我的 CLogger 类是我使用本教程创建的单例类:yolinux.com/TUTORIALS/C++Singleton.html 在这种情况下,我将引用所有使用 CLogger::instance()-&gt;myMethodOrMember 的方法和成员。我不知道如何调用新创建的对象。我想也许CLogger::instance &lt;&lt; "test" 但不是...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多