流操作符和控制转换优先级

时间:2015-11-17 21:33:12

标签: c++ inheritance virtual-inheritance

我有一个流媒体基类:

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,并使用非成员流操作符的问题。

有没有办法优先考虑演员?

1 个答案:

答案 0 :(得分:0)

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

// 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会很友善吗?