G ++没有预期的编译错误。而是进行“随机”转换

时间:2014-02-06 19:17:15

标签: c++ compiler-construction implicit-conversion

我有一个奇怪的错误,编译接受代码,但是隐式构造一个类型。以前,在我为Value类添加构造函数之前,这不会编译。下面是我的代码如何设置的示例,但是无法按预期编译。

#include <iostream>
#include <cassert>


enum class Type {
    Null = 0
    ,Char
    ,Int32
    //etc
};


// My variant class.
class Value {
public:
// I also have templated constructors for Value...
    Value( Type type, void* data = nullptr ) {
        //construct type from data.
        assert( false );
    }
    friend std::ostream& operator<<( std::ostream& os, const Value& v);
};

// If the insertion operator is defined globally, not within the class, then the compiler
// will do the implicit conversion.
std::ostream& operator<<( std::ostream& os, const Value& v) {
    return os << "Printing Value";
}

// In my code, what this really does is get the type from the lua stack
// and converts the type to my own. I'll just do a c style cast here.
Type getType( int i ) { return (Type)i; }


int main() {
    // In my code, this statement compiles, but implicitly constructs Value 
    // from the return type "Type".
    std::cout << getType( 2 ) << "\n";
    return 0;
}

以前有人遇到过这个问题吗?是否有任何语言功能会导致这种情况发生?我应该寻找哪些类型的东西来防止这种情况发生?(我知道我可以改变构造函数来要求“data”参数,但我正在寻找根本原因)

编辑:我想出了允许编译器进行隐式转换的内容,见下文。

1 个答案:

答案 0 :(得分:2)

您的类有一个转换构造函数,它将Type类型的对象转换为Value

类型的对象
Value( Type type, void* data = nullptr ) {
    //construct type from data.
    assert( false );
}

那么你就写了

std::cout << getType( 2 ) << "\n";

运营商&lt;&lt;类型类型没有重载。因此,编译器尝试将运算符的操作数隐式转换为可以与运算符一起使用的类型。它找到了这样的转换,因为你有转换构造函数。

您应该将构造函数声明为

explicit Value( Type type, void* data = nullptr );