How to define a static operator<<?

前端 未结 4 959
终归单人心
终归单人心 2021-01-03 06:37

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         


        
相关标签:
4条回答
  • 2021-01-03 07:17

    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.

    0 讨论(0)
  • 2021-01-03 07:17

    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";
    
    0 讨论(0)
  • 2021-01-03 07:18

    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

    0 讨论(0)
  • 2021-01-03 07:18

    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.

    0 讨论(0)
提交回复
热议问题