Базовый тип перечисления C++ в C++ 0x

new fabric.Canvas() возвращает не элемент DOM Canvas, а объект Canvas FabricJS с собственным набором атрибутов и методов. Если вы хотите получить доступ к фактическому холсту, который рисует FabricJS, есть метод getElement () :

var newCanvas = new fabric.Canvas("myId");
var newCanvasId = newCanvas.getElement().id; // "myId"

27
задан Johannes Schaub - litb 2 October 2011 в 10:36
поделиться

4 ответа

Я не читал никаких материалов по C ++ 0x, поэтому не могу это прокомментировать.

Что касается сериализации, вам не нужен переключатель при чтении перечисления обратно - просто приведите его к типу перечисления.

Тем не менее, я не разыгрываю при записи в поток. Это потому, что мне часто нравится писать оператор < < для перечисления, так что я могу отловить записываемые неверные значения или затем принять решение выписать строку вместо этого.

enum color { red, green, blue };
color c = red;

// to serialize
archive << c;    // Removed cast

// to deserialize
int i;
archive >> i;
c = (color)i;    // Removed switch
5
ответ дан markh44 28 November 2019 в 05:24
поделиться

Что касается enum class color: это C ++ / CLI (C ++ .NET) или будущий код C ++ 0x?

Для сериализации вы можете получить размер перечисления с помощью sizeof(color), чтобы узнать, сколько байтов для копирования.

1
ответ дан Dario 28 November 2019 в 05:24
поделиться

enum class is a C++0x feature, it is not present in C++03.

In standard C++, enumerations are not type-safe. They are effectively integers, even when the enumeration types are distinct. This allows the comparison between two enum values of different enumeration types. The only safety that C++03 provides is that an integer or a value of one enum type does not convert implicitly to another enum type. Additionally, the underlying integral type, the size of the integer, cannot be explicitly specified; it is implementation defined. Lastly, enumeration values are scoped to the enclosing scope. Thus, it is not possible for two separate enumerations to have matching member names. C++0x will allow a special classification of enumeration that has none of these issues. This is expressed using the enum class declaration

Examples (from the wikipedia article):

enum Enum1;                   //Illegal in C++ and C++0x; no size is explicitly specified.
enum Enum2 : unsigned int;    //Legal in C++0x.
enum class Enum3;             //Legal in C++0x, because enum class declarations have a default type of "int".
enum class Enum4: unsigned int; //Legal C++0x.
enum Enum2 : unsigned short;  //Illegal in C++0x, because Enum2 was previously declared with a different type.

As for the serialization part (which I think was not part of the original question), I prefer to create a helper class that translates enum items into their string equivalent (and back), as the names are usually more stable than the integer values they represent, as enum items can be (and sometimes are) reordered without changing the code behavior.

16
ответ дан 28 November 2019 в 05:24
поделиться

Я решил создать новый ответ, потому что мой старый был очень беспорядочным. В любом случае просто хочу сказать кое-что о C ++ 11, где вы можете получить базовый тип перечисления, используя это:

std::underlying_type_t<E>

И, ради интереса, идея разрешения перегрузки. Но, пожалуйста, используйте имена для хранения перечисления, как предлагает @lothar.

Разрешение перегрузки проистекает из того факта, что существует одно повышение от перечисления до первого типа int, unsigned int, long, unsigned long, которое может представлять все значения его базового типа. Преобразование в любой другой целочисленный тип имеет более низкий ранг, и разрешение перегрузки не предпочтет его.

char (& f(int) )[1];
char (& f(unsigned int) )[2];

char (& f(long) )[3];
char (& f(unsigned long) )[4];

char const* names[] = { 
    "int", "unsigned int", 
    "long", "unsigned long"
};

enum a { A = INT_MIN };
enum b { B = UINT_MAX };
enum c { C = LONG_MIN };
enum d { D = ULONG_MAX };

template<typename T> void print_underlying() {
    std::cout << names[sizeof(f(T()))-1] << std::endl;
}

int main() { 
    print_underlying<a>();
    print_underlying<b>();
    print_underlying<c>();
    print_underlying<d>();
}

И он печатает вот это:

int
unsigned int
int
unsigned int

Это не представляет особого интереса для этой проблемы сериализации (поскольку размер сериализованных данных равен не постоянной ширины, и это может вызвать проблемы при изменении перечисления и его базового типа), но обычно интересно выяснить тип, хранящий все перечисление. Ура!

14
ответ дан 28 November 2019 в 05:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: