c++ - 选择性隐式转换

标签 c++ implicit-conversion ostream

我有一个 Value可以保存各种数据类型的值的类。

class Value
{
    private:
        union
        {
            int Integer;
            double Real;
            bool Boolean;
        };

        ValueTypes valType;

    public:
        Value();
        Value(double Val);
        Value(int Val);
        Value(bool Val);

        /* ... */

        friend std::ostream& operator <<(std::ostream& stream, const Value& val);
}

我想重载 <<运算符,因此可以打印值而无需调查其类型。

这是我当前的实现:

std::ostream &operator <<(std::ostream &os, const Value &val)
{
    switch (val.valType)
    {
        case ValueTypes::Real:
            os << val.Real;
            break;

        case ValueTypes::Integer:
            os << val.Integer;
            break;

        case ValueTypes::Boolean:
            os << (val.Boolean ? "True" : "False");
            break;
    }

    return os;
}

首先,当使用 g++(CodeBlocks IDE、Ubuntu)编译时,实现会导致隐式转换为 Value。 .当值类型是 Integer 时或 Real , os <<语句将它们转换为 Value ,然后调用 ostream再次重载(无限递归),所以我最终遇到了段错误。

其次,当用 Visual C++ 编译时,隐式转换消失了,它打印的值很好(不调用隐式构造函数)。

注释:

我希望保留隐式构造函数,因为它增强了可读性并简化了我项目其他部分的维护。

此外,我还发现了以下blog post , 但未能调整我的代码使其按我希望的方式执行(模板的使用有点超出我目前对 cpp 语法的理解)。

我该怎么做才能在特定的 ostream 中禁用隐式转换?重载函数?

编辑:-Wall已启用,我在 CodeBlocks 中没有收到任何警告。

最佳答案

您需要 #include <ostream> .没有它就不能工作的原因是因为这是实际定义 std::ostream 的 header 。以及所有有用的 operator<<功能。

它没有 panic 并提示“没有定义 std::ostream”(或其他 << 运算符)的原因是前向声明。如果您转发声明一个类型,您可以将它用作指针或引用(只要您不尝试进一步访问它)。 You can do some things with an incomplete type .

您包含的其他 header 可能是前向声明 std::ostream , 但从未给出它和所有 << 的完整定义运营商。至少在你的 Ubuntu 系统上。在其他系统上,其他 header 可能包含 <ostream>或者至少提供了一些 <ostream> 的定义做。你的operator<<可能是编译器看到的唯一一个(因为您没有包括 <ostream> ),并且由于它是编译器唯一知道的一个,它试图将它用于所有事情。

简而言之,在处理跨平台内容时,应该小心翼翼地包含确切的必要内容(而不是依赖其他 header 来包含与其无关的内容)。

关于c++ - 选择性隐式转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22585270/

相关文章:

ruby - 从 nil 到 hash 的隐式转换有 refine bug

c++ - 自己的输出流(mock cout)

c++ - C++ ostream (tostring) 的最佳实践

c++ - 将位图转换为垫子

scala - 为什么 scala 编译器在重载且具有泛型类型参数时无法找到隐式参数值/转换?

scala - 为什么当 scala.language.implicitConversions 不是最后一次导入时发出警告?

c++ - 尝试重载时出现语法错误 "<<": too many parameters

c++ - 将私有(private)对象变量与用户输入的变量进行比较

c++ - 为什么我在将 tolower() 的结果流式传输到 std::cout 时得到一个数字,但在我使用 putchar() 时却没有?

c++ - C++ 的 Visual Studio 文档