static方法不会调用inline basic_stream<<枚举的运算符

时间:2014-01-21 15:19:34

标签: c++ operator-overloading static-members

我有这个枚举类型确定对象foo的状态:

enum fooStatus
{
    DOWN = 0,
    TEMPORARY_DOWN = 1,
    UP = 2
};

对于这个fooStatus枚举,我编写了一个basic_ostream运算符,用于从枚举向后转换为可读形式,用于记录如下:

template<
    typename CH,
    typename TRAITS
>
inline std::basic_ostream<CH, TRAITS>& operator<<(
    std::basic_ostream<CH, TRAITS>& os,
    fooStatus& status
)
{
    switch (status)
    {
        case DOWN:
            os << "DOWN";
            break;

        case TEMPORARY_DOWN:
            os << "TEMPORARY_DOWN";
            break;

        case UP:
            os << "UP";
            break;

        default:
            os << "UNKNOWN STATUS";
            break;
    }
    return os;
}

现在,这个工作正常,直到我创建了foo的静态成员函数,我想要打印出我存储的所有foo对象的所有状态。

foo.h中:

static std::string get_all_statuses();

foo.cxx:

std::string get_all_statuses() {
    ... 
    std::ostringstream result;
    foreach(foo in fooStorage) { //<-- non c++ simplification
        result << foo->get_status() << ","; /* get_status returns the fooStatus enum type*/
    }
    return result.str();
}

可悲的是,这个'get_all_statuses'静态函数调用返回一个包含数字的字符串,而不是&lt;&lt;&lt;&lt;以上运营商。在foo的成员函数中的foo.cxx文件中的成员get_status()函数上应用运算符可以正常工作。我似乎无法理解这里的一些基础知识,我的同事也找不到解决方案。

因此,我的问题是两个:

首先,这种行为背后的确切逻辑是什么? (期望类似编译器在静态函数编译时不知道内联运算符)

其次,使这项工作符合预期的最佳做法是什么?

1 个答案:

答案 0 :(得分:2)

据推测,get_status按值返回fooStatus,该值不能绑定到operator<<签名中的可变引用。您需要在fooStatus&的重载中将const fooStatus&更改为operator<<,这将正确绑定。

#include <iostream>

enum fooStatus
{
    DOWN = 0,
    TEMPORARY_DOWN = 1,
    UP = 2
};

template<
    typename CH,
    typename TRAITS
>
inline std::basic_ostream<CH, TRAITS>& operator<<(
    std::basic_ostream<CH, TRAITS>& os,
    const fooStatus& status
)
{
    switch (status)
    {
        case DOWN:
            os << "DOWN";
            break;

        case TEMPORARY_DOWN:
            os << "TEMPORARY_DOWN";
            break;

        case UP:
            os << "UP";
            break;

        default:
            os << "UNKNOWN STATUS";
            break;
    }
    return os;
}

int main()
{
    std::cout << TEMPORARY_DOWN;
    return 0;
}