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

问题描述 投票:0回答:1

我遇到了一个奇怪的错误,编译器接受代码,但执行类型的隐式构造。以前,除非我为 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”参数,但我正在寻找根本原因)

编辑:我弄清楚了什么允许编译器进行隐式转换,请参见下文。

c++ implicit-conversion
1个回答
2
投票

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

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

那么你就写吧

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

操作员<< is not overloaded for type Type. So the compiler tries to convert implicitly the operand of the operator to type that can be used with the operator. And it finds such conversion because you have the conversion constructor.

您应该将构造函数声明为

explicit Value( Type type, void* data = nullptr );
© www.soinside.com 2019 - 2024. All rights reserved.