【发布时间】:2012-08-13 14:54:46
【问题描述】:
所以我在 c++ 中有一个虚拟流接口
class KxStream
{
public:
virtual KxStream& operator<< ( u32 num ) = 0;
};
它为所有内置类型提供了大量基本的
然后我有几个实现流接口的类。像这样:
class KxCbuf : public KxStream
{
public:
KxStream& operator<<( u32 num );
}
所以在 KxCbuf 中有一个流接口的实现。到现在为止还挺好。然后我有一些重载流接口的类:
class KxSymbol
{
operator u32() const;
friend KxStream& operator<<( KxStream& os, KxSymbol sym );
};
请注意,此类已将运算符强制转换为内置类型。现在,当我尝试将这些类之一流式传输到实现流式接口的类之一时,我收到一个错误:
KxCbuf buf;
KxSymbol sym;
buf << sym; // error!
编译器对使用哪些函数感到困惑。 Gcc 编译得很好,但是说有多种方法可以做到这一点。 MSVC 没有编译说有多个重载:
src/variable.cpp(524) : error C2666: 'KxCbuf::operator <<' : 15 overloads have similar conversions
我知道发生了什么,只是不知道如何令人满意地解决它。所以编译器可以要么强制转换 KxCbuf -> KxStream,然后调用友元函数,这是正确的做法。或者它可以强制转换KxSymbol -> u32,然后调用KxCbuf中的u32
我可以用两种(坏的)方法解决它。
我可以从流式传输开始:
buf << "" << sym;
这样第一个流操作符的返回值“”返回KxStream,一切正常。或者我可以为实现类实现一个冗余的流操作符。例如。我可以将以下内容添加到 KxSymbol:
friend KxStream& operator<<( KxCbuf& os, KxSymbol sym );
第一个答案总是有效的 - 但它确实很难看。第二个答案也很丑陋,因为我必须创建冗余的流运算符,并且并不总是有效,因为 KxStream 实现并不总是在我需要定义新的流运算符的地方可见。
理想情况下,我希望 KxStream 接口的实现像 KxStream 对象一样工作,并避免导致模糊转换的隐式转换。
我该如何解决这个问题?
(ps。我需要为我的库的自定义序列化方案创建自己的流操作符。我不能使用具有自己的序列化类的 boost 或类似的第三方库)
@Edit:有几个很好的答案与控制编译器对隐式转换的使用有关,比如转换为 KxSymbol -> u32,不幸的是隐式转换对代码很重要。例如,KxSymbol 是一个将字符串存储在表格中并将它们作为数字返回的类,以便我可以将字符串作为数字进行比较。例如。如果两个符号不相等,则字符串不相同。我还在某些数据结构中将符号存储为数字。
有没有办法从另一方面解决这个问题,不知何故让编译器明白,应该优先将 KxStream 的实现转换为 KxStream 对象而不是其他隐式转换?
例如,如果我以某种方式强制编译器必须首先将 KxCbuf 强制转换为 KxStream,然后再将 operator
【问题讨论】:
-
如果你通过 const 引用而不是复制传递`KxSymbol sym`会发生什么?这可能解决问题
标签: c++ serialization