如何定义静态运算符<<?

发布于 2024-12-17 14:13:30 字数 547 浏览 3 评论 0 原文

是否可以定义一个仅对类的静态成员进行操作的静态插入运算符?比如:

class MyClass
{
public:
    static std::string msg;

    static MyClass& operator<< (const std::string& token) {
        msg.append(token);
        return *this;   // error, static
    }
};

或者:

static MyClass& operator<< (MyClass&, const std::string &token)
{
    MyClass::msg.append(token);
    return ?;
}

这就是我想使用它的方式:

MyClass << "message1" << "message2";

谢谢!

Is it possible to define a static insertion operator which operates on the static members of a class only? Something like:

class MyClass
{
public:
    static std::string msg;

    static MyClass& operator<< (const std::string& token) {
        msg.append(token);
        return *this;   // error, static
    }
};

alternatively:

static MyClass& operator<< (MyClass&, const std::string &token)
{
    MyClass::msg.append(token);
    return ?;
}

This is how I would like to use it:

MyClass << "message1" << "message2";

Thank you!

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

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

发布评论

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

评论(4

木落 2024-12-24 14:13:30

在您的情况下,我可能会做的是创建另一个重载运算符<<的类,然后创建该类型的静态成员。像这样:

class MyClass
{
public:
    static std::string msg;

    struct Out {
        Out & operator<< (const std::string& token) {
            MyClass::msg.append(token);
            return *this;
        }
    };

    static Out out;    
};

使用它并不是您所要求的,但我认为足够接近:

MyClass::out << "message1" << "message2";

What I would probably do in your situation, is create another class that overloads the operator<<, then make a static member of that type. Like this:

class MyClass
{
public:
    static std::string msg;

    struct Out {
        Out & operator<< (const std::string& token) {
            MyClass::msg.append(token);
            return *this;
        }
    };

    static Out out;    
};

Using it is not quite what you asked for, but close enough I think:

MyClass::out << "message1" << "message2";
双马尾 2024-12-24 14:13:30

如果 MyClass 的所有成员都是静态的,则可以返回一个新的实例。

然而,返回引用会带来问题。有两种解决方案:

  • 定义一个
  • 通过复制传递的静态实例,而不是通过引用传递。

第二种方法是最简单的:

static MyClass operator<< (MyClass, const std::string &token)
{
     MyClass::msg.append(token);
     return MyClass();
}

第一种方法是多一行:

static MyClass& operator<< (MyClass&, const std::string &token)
{
     static MyClass instance;

     MyClass::msg.append(token);
     return instance;
}

用法非常接近您想要的:

MyClass() << "message1" << "message2";

但是,我不建议这样做。为什么不直接使用 std::ostringstream 呢?您将免费获得格式设置等服务。如果您确实需要全局访问,请声明一个全局变量。

If all the members of MyClass are static, it's possible to return a fresh instance.

However, returning a reference poses a problem. There are two solutions:

  • define a static instance
  • pass by copy, and not by reference.

The second approach is easiest:

static MyClass operator<< (MyClass, const std::string &token)
{
     MyClass::msg.append(token);
     return MyClass();
}

The first is one line more:

static MyClass& operator<< (MyClass&, const std::string &token)
{
     static MyClass instance;

     MyClass::msg.append(token);
     return instance;
}

Usage is very close to what you want:

MyClass() << "message1" << "message2";

However, I would not recommend to do this. Why don't you just just use a std::ostringstream? You'll get formatting and some more for free. If you really need global access, declare a global variable.

你的往事 2024-12-24 14:13:30

如果你想使用你的类作为cout,你可以做的是示例

#include <iostream>
using namespace std;
namespace trace
{
  class trace
  {
  public:
    trace& operator<< (const std::string& echo)
    {
      std::cout << echo << std::endl;
      return *this;
    }
  };

  trace t; // Note that we created variable so we could use it.
};

using namespace trace; // Note that we use same namespace so we dont need to do trace::t
int main(int argv, char** argc)
{
  t << "Server started..."
    << "To exit press CTRL + Z";
  return 0;
}

输出应该看起来像新行中的每个字符串,如下所示:

服务器已启动...
要退出,请按 CTRL + Z

If you want to use your class as cout, what you can do is example

#include <iostream>
using namespace std;
namespace trace
{
  class trace
  {
  public:
    trace& operator<< (const std::string& echo)
    {
      std::cout << echo << std::endl;
      return *this;
    }
  };

  trace t; // Note that we created variable so we could use it.
};

using namespace trace; // Note that we use same namespace so we dont need to do trace::t
int main(int argv, char** argc)
{
  t << "Server started..."
    << "To exit press CTRL + Z";
  return 0;
}

Output should look like each string in new line like this:

Server started...
To exit press CTRL + Z

半世蒼涼 2024-12-24 14:13:30

你不能。类名/类型本身不是值,您需要一个类似的表达式

class Foobar {...};

std::cout << Foobar << std::endl;

,以便您的静态运算符<<可用,但这不是有效的C++。 A.4 的语法摘要表明,将类型名称放在那里是无效的。

还要考虑到运算符重载只是名称不固定的函数:

T  operator<< (T, T)
   ^^^^^^^^^^ flaky name, basically same as:
T  left_shift (T, T)

C++(以及大多数其他语言,例如 C#)中的函数只能作用于类型的实例,而不能作用于类型本身。

然而,C++ 提供了具有类型参数的模板,但这并不能帮助您根据类型重载函数。

You can't. A class-name / type is not a value in itself, you would need an expression like

class Foobar {...};

std::cout << Foobar << std::endl;

so that your static operator<< would be usable, but that is not valid C++. The grammar summary at A.4 shows that putting a type's name there is not valid.

Consider also that operator overloads are just functions with flaky names:

T  operator<< (T, T)
   ^^^^^^^^^^ flaky name, basically same as:
T  left_shift (T, T)

And functions in C++ (and most other languages, e.g. C#) can only work on instances of types, not types themselves.

However, C++ offers templates which have type arguments, howhowever, that would not help you to overload functions upon types.

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