How to define a static operator <<?

Is it possible to define a static insert statement that only works with static members of a class? Sort of:

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

as an alternative:

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

Here is how I would like to use it:

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

Thanks!

+4
source share
4 answers

If all MyClass members are static, you can return a new instance.

However, returning the link creates a problem. There are two solutions:

  • define a static instance
  • transfer a copy, not a link.

The second approach is easiest:

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

The first is another line:

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

Use is very close to what you want:

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

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

+4
source

What I will probably do in your situation will create another class that overloads operator<< and then make a static member of this 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 this is not quite what you requested, but close enough, I think:

 MyClass::out << "message1" << "message2"; 
+10
source

If you want to use your class as cout, then you can make an 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; } 

The output should look like every line in a new line as follows:

Server is running ... To exit, press CTRL + Z

+1
source

You can not. Type / class name is not in itself, you need an expression like

 class Foobar {...}; std::cout << Foobar << std::endl; 

so that your static operator<< is useful, but this is not valid with C ++. The grammar summary in A.4 indicates that the placement of the type name 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, such as C #) can only work with type instances, and not with the types themselves.

However, C ++ offers templates with type arguments, but that will not help you to overload functions by type.

0
source

Source: https://habr.com/ru/post/1382742/


All Articles