如何定义静态运算符&lt; <! - ? - >

时间:2011-11-23 17:28:44

标签: c++ static operator-keyword insertion

是否可以定义静态插入操作符,该操作符仅对类的静态成员进行操作?类似的东西:

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";

谢谢!

3 个答案:

答案 0 :(得分:10)

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

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";

答案 1 :(得分:4)

如果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?你会免费获得格式化和更多。如果您确实需要全局访问,请声明一个全局变量。

答案 2 :(得分:0)

你做不到。类名/类型本身不是一个值,你需要一个像

这样的表达式
class Foobar {...};

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

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

还要考虑运算符重载只是具有片段名称的函数:

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

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

但是,C ++提供了具有类型参数的模板,无论如何都不会帮助您在类型上重载函数。