运算符重载问题

时间:2013-09-30 13:59:24

标签: c++ operator-overloading

我明确地在班级定义中有朋友并且更清楚,删除了实施代码等......

class Ref
{
    public:
        Ref(char* s, size_t l) : _s(s), _l(l) {}
    private:
        char* _s;
        size_t _l;
};

class foo
{
    public:
        friend stringstream& operator>>(std::stringstream& s, uint8_t& v) { return s; }
        friend stringstream& operator>>(std::stringstream& s, const Ref& r) { return s; }
    private:
        std::stringstream ss;
        void example(void)
        {
            char b[256];
            Ref r(b, sizeof(b));
            uint8_t i;

            ss >> i >> r;    <------ Why do I get an error here?
            ss >> r >> i;    <------ But this one seems to compile fine.
        }
};

2 个答案:

答案 0 :(得分:6)

为什么你在std::stringstream上超载?你应该 总是在std::istreamstd::ostream上超载 (取决于方向)。这非常罕见 甚至可以使用std::stringstreamstd::istringstreamstd::ostringstream通常更合适),和 即使它们是,operator>>通常会返回 一个std::istream&,而不是std::stringstream&

编辑:

关于为什么一个人似乎工作:

ss >> r >> i;

operator>>( operator>>( ss, r ), i );

您已定义operator>>,其中stringstream&Ref const&,因此内部调用有效。和你的 operator>>会返回stringstream&,其中 std::istream,因此可以调用函数operator>>( std::istream&, unsigned char )。在哪里:

ss >> i >> r;

operator>>( operator>>( ss, i ), r );

内部调用返回std::istream&,但没有 已为operator>>重载std::istream&, Ref const&

如上所述:重载的>>始终采取 std::istream&作为第一个参数,并返回一个 std::istream&

答案 1 :(得分:1)

ss >> i >> r;   <-------  why do I get an error here?

您忘了告诉我们错误是什么,或者发布给您错误的实际代码。当我修复已发布代码中的明显错误时,我得到:

cannot bind ‘std::basic_istream<char>’ lvalue to ‘std::basic_istream<char>&&’

第一个问题是ss >> i不会调用你的超载;你不能为像uint8_t这样的内置类型重载流操作符。因此,这将调用标准库定义的重载,该库返回对istream的引用,而不是stringstream。您的运营商需要引用stringstream,因此第二个运营商将失败。

您应遵循惯例并使用通用ostream而非特定stringstream

friend std::istream& operator>>(std::istream& s, const Ref& r) { return s; }

如果您确实希望操作员执行任何有用的操作,那么您需要从第二个参数中删除const