0

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

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

2 回答 2

5

你为什么超载std::stringstream?您应该始终超载std::istreamstd::ostream (取决于方向)。它 std::stringstream甚至会被使用(std::istringstream或者 std::ostringstream通常更合适)是非常罕见的,即使它们被使用,operator>>通常也会返回 a std::istream&,而不是 a std::stringstream&

编辑:

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

ss >> r >> i;

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

您已经定义了一个operator>>接受stringstream& and的 an Ref const&,因此内部调用是有效的。并且您 operator>>返回 a stringstream&,即isA ,因此可以调用std::istream该函数。operator>>( std::istream&, unsigned char )然而:

ss >> i >> r;

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

内部调用返回一个std::istream&,并且没有重载operator>>for std::istream&, Ref const&

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

于 2013-09-30T14:07:57.710 回答
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从第二个参数中删除 。

于 2013-09-30T14:16:22.070 回答