运算符过载问题

Operator overloading problems

本文关键字:问题 运算符      更新时间:2023-10-16

>我显然在类定义中有朋友,为了更清楚,删除了实现代码等......

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.
        }
};

你为什么要在std::stringstream上过载? 你应该始终在std::istreamstd::ostream上过载(取决于方向)。 这是非常罕见的 甚至会使用std::stringstreamstd::istringstreamstd::ostringstream通常更合适),以及即使他们是,operator>>通常会回来一个std::istream&,而不是一个std::stringstream&

编辑:

关于为什么一个似乎有效:

ss >> r >> i;

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

您已经定义了一个需要stringstream&operator>>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& .

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