我明确地在班级定义中有朋友并且更清楚,删除了实施代码等......
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.
}
};
答案 0 :(得分:6)
为什么你在std::stringstream
上超载?你应该
总是在std::istream
或std::ostream
上超载
(取决于方向)。这非常罕见
甚至可以使用std::stringstream
(std::istringstream
或
std::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
。