所以我在C++中有一个虚拟流接口(interface)

class KxStream
{
public:
   virtual KxStream& operator<< ( u32 num ) = 0;
};

对于所有内置类型,它都有大量的基本<
然后,我有一些实现流接口(interface)的类。像这样:
class KxCbuf : public KxStream
{
public:
   KxStream& operator<<( u32 num );
}

因此,在KxCbuf中有一个流接口(interface)的实现。到现在为止还挺好。然后我有一些类重载了流接口(interface):
class KxSymbol
{
   operator u32() const;
   friend KxStream& operator<<( KxStream& os, KxSymbol sym );
};

请注意,此类已将运算符强制转换为内置类型。现在,当我尝试将其中一个类流式传输到实现流式接口(interface)的一个类中时,我得到一个错误:
KxCbuf buf;
KxSymbol sym;

buf << sym; // error!

编译器对于要使用哪些功能感到困惑。 Gcc可以很好地编译,但是说有多种方法可以做到这一点。 MSVC不会编译说有多个重载:
src/variable.cpp(524) : error C2666: 'KxCbuf::operator <<' : 15 overloads have similar conversions

我知道发生了什么,只是不知道如何令人满意地解决它。因此,编译器可以强制转换KxCbuf-> KxStream,然后调用friend函数,这是正确的做法。或者,它可以强制转换KxSymbol-> u32,然后在继承自KxStream的KxCbuf中调用u32 <
我可以用两种(坏的)方法解决它。

我可以先流式传输一些明确的内容:
buf << "" << sym;

这样,“”的第一个流运算符的返回值将返回KxStream,一切都很好。或者,我可以为实现类实现一个冗余的流运算符。例如。我可以将以下内容添加到KxSymbol中:
friend KxStream& operator<<( KxCbuf& os, KxSymbol sym );

第一个答案始终有效-但它确实很丑陋。第二个答案也很丑陋,因为我必须创建冗余的流运算符,并且并不总是有效,因为在需要定义新的流运算符的地方,KxStream实现并不总是可见的。

理想情况下,我希望KxStream接口(interface)的实现像KxStream对象一样工作,并避免导致模棱两可的转换的隐式强制转换。

我该如何解决?

(ps。我需要为我的库的自定义序列化方案创建自己的流操作符。不能使用具有自己的序列化类的boost或类似的第三方库)

@Edit:有许多与控制编译器对隐式转换的使用相关的好答案,例如转换为KxSymbol-> u32,不幸的是,隐式转换对代码很重要。例如,KxSymbol是一个将字符串存储在表中并以数字形式返回的类,这样我就可以将字符串作为数字进行比较。例如。如果两个符号不相等,则字符串不相同。我还在某些数据结构中将符号存储为数字。

有没有另一种方法可以解决此问题,以某种方式使编译器理解应该优先于其他隐式强制转换将KxStream的实现强制转换为KxStream对象?

例如,如果我以某种方式迫使编译器必须先将KxCbuf转换为KxStream,然后再对内置类型使用operator <

最佳答案

如果您具有C++ 11编译器,则将转换函数标记为“explicit”。这样,您将不会隐式转换为u32,这种歧义将消失。

关于c++ - C++中的流接口(interface)问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11936870/

10-11 18:24