2016-11-30 5 views
1

Рассмотрим этот код:Почему я не получаю предупреждение о несоответствии сравнения перечислений?

typedef enum Type1 
{ 
    val11, 
    val12 
} Type1; 

typedef enum Type2 
{ 
    val21, 
    val22 
} Type2; 

Type1 type1 = val11; 
if (type1 == val22) 
    std::cout << "foo"; 

Visual Studio 2015 не выдает никаких предупреждений (даже с/Wall). Однако type1 и val22 не одного типа. Это нормально или это ошибка Visual Studio?

+0

, если это что-то вроде C# перечислений только при поддержке целого, так что если справедливо в C++ это может быть возможно, что эквивалентно 'если (type1 == 1)' – Kritner

+0

Это нормально. Обе стороны оператора равенства переводятся в 'int'. – Leon

+3

Напишите современный код на C++, используйте 'enum class'. –

ответ

0

Насколько я знаю, компилятор не обязан выдавать предупреждение при сравнении перечислений разных типов. Я не мог найти его в стандарте. Для классических типов перечислений существует неявное преобразование типа в int, поэтому полученный код совершенно легален. Семантически часто бывает некорректно сравнивать перечисления разных типов, поэтому, поскольку C++ у нас есть областная структура перечисления, которая не допускает неявных преобразований. (См. Код ниже).

#include <iostream> 
using namespace std; 

enum UE1 // This is an unscoped enumeration (since C) 
{ 
    val11, 
    val12 
}; 

enum UE2 // This is an unscoped enumeration too 
{ 
    val21, // have to use different names for enumeration constants 
    val22 
}; 

enum class SE1 // This is an scoped enumeration (since C++11) 
{ 
    val1, 
    val2 
}; 

enum class SE2 
{ 
    val1, // can use the same names for the constants 
    val2 // because they are in the different scope 
}; 

int main(int, char**) 
{ 
    if (val11 == val22) // implicit conversion from an enum to int is available 
     cout << "UE::val11 is equal to UE::val22" << endl; 

    if (static_cast<int>(SE1::val1) == static_cast<int>(SE2::val1)) // have to apply explicit conversion 
     cout << "SE1::val1 is equal to SE2::val1" << endl; 

    if (SE1::val1 == SE2::val1) // error!!! Cannot make implicit conversions from a scoped enumeration. 
     cout << "SE1::val1 is equal to SE2::val1" << endl; 

    return 0; 
}