流运算符和控制转换优先级

Stream operator and controlling conversion priority

本文关键字:转换 优先级 控制 运算符      更新时间:2023-10-16

我有一个流式基类:

class Stream
{
   virtual Stream& operator<< ( float num ) = 0;
   virtual Stream& operator<< ( double num ) = 0;
   virtual Stream& operator<< ( bool val ) = 0;
};

然后我实现了一个实现类:

class StreamImpl : public Stream
{
   Stream& operator<< ( float num  ) { ... do stuff ... }
   Stream& operator<< ( double num ) { ... do stuff ... } 
   Stream& operator<< ( bool val   ) { ... do stuff ... }
};

然后,对于新的类,我创建了我的非成员流运算符函数:

class Blar { };
Stream& operator<< ( Stream& str, const Blar& blar ) { ... do stuff ... }

它运行得很好。但我遇到的问题是,在某些情况下,编译器不知道该使用哪个流运算符。

考虑Blar何时具有投射操作符:

class Blar 
{
    operator bool() const {  return false; }
};

现在我尝试使用流:

void process( Stream& str )
{
    Blar blar;
    str << blar;
}

因此,编译器不知道是否应该将Blar转换为bool,然后使用Stream成员,或者将str转换为Stream类型,然后使用非成员流运算符。

有没有办法确定演员阵容的优先级?

这个模板和SFINAE有望消除歧义(通过为从Stream派生的每个类定义operator<<,从而消除str << blar左侧的隐式转换):

// the following operator could potentially be defined in the template below, I'm just extending your code
Stream& operator<< (Stream& str, const Blar& blar) { /* something */ return str; }
template <
    typename Str,
    typename = typename std::enable_if<
        std::is_base_of<Stream, Str>::value &&
        !std::is_same<Stream, Str>::value
    >::type
>
Stream& operator<< (Str& str, const Blar& blar) { return static_cast<Stream&>(str) << blar; }

但是,即使对我来说,它看起来也只是一个额外的混乱,需要复习——也许@R Sahu会这么做吗?