操作员<<奇怪的行为

operator << strange behaviour

本文关键字:lt 操作员      更新时间:2023-10-16

我有一个名为Log的类,它重载了运算符<lt;:

class Log
{
     public:
        static void init(std::ostream&);
        Log(const std::string&);
        ~Log(); //Write to the log here
        Log& operator<<(bool);
        Log& operator<<(const std::string&);
     private:
        std::stringstream text;
        static std::ostream *stream;
        std::string tag;
};

好的,问题是,当我这样写日志时:

int main()
{
    std::ofstream file;
    file.open("log.txt",std::ios::app);
    Log::init(file);
    Log("[INFO]") << "Test";
    file.close();
}

运算符<lt;它接收一个bool被调用,将true写入日志。。。,如果我删除了接收到bool的运算符实现,那么另一个就被正确调用了。我认为发生这种情况是因为char*可以被解释为bool。。。但是我该怎么修呢??

创建第三个采用char *参数的operator<<重载。

我认为你对这个问题的分析可能是正确的,尽管令人惊讶。

有两个可能的<<运算符,一个采用std::string,一个采取bool。第一个需要用户定义的转换,从char数组构造一个std::string对象。第二个需要标准的转换,将指针转换为bool(空指针变为false,非空指针变成true)。这里的规则是,标准转换优于用户定义的转换(13.3.3.2[over.ics.rank]/2),因此编译器选择bool版本。

您可以删除所有运算符<lt;在你的课堂上,并有一个模板:

template <typename T> 
Log& operator << (Log& log, const T& value) {
    // ...
    return log;
}

替换<lt;(bool)通过<lt;(OnlyBool),其中OnlyBool定义为:

struct OnlyBool
{
    OnlyBool(bool b)  : m_b(b){}
    bool m_b;
};

这个想法是使用一个从bool隐式创建的类型,但只使用bool。

(很抱歉简洁,我在手机上写这篇文章)