2013-02-15 1 views
3

разыменования типа каламбурилPass перечисление в функции принимает ссылку на Int

У меня есть перечисление

enum AgentStatus { kSTOPPED = 0, kRUNNING, kIDLE, kNAGENTSTATUS }; 

мне нужно передать его функции внешней библиотеки с большим количеством перегруженных вариантов. Я хочу передать его второму аргументу:

DimService::DimService(const char*, int&); 
DimService::DimService(const char*, char*); 
... 

Если бы я сделать бросок к (INT &) моей переменной перечислимого, я получаю позорный предупреждение:

warning: dereferencing type-punned pointer will break strict-aliasing rules 

Если я слепок to (int) Я получаю это

invalid conversion from ‘int’ to ‘char*’ 
error: initializing argument 2 of ‘DimService::DimService(const char*, char*)’ 

Каков правильный путь?

+2

Использовать переменную int, а не лить. – PlasmaHH

+0

это ссылка, не нужно использовать –

+0

'enum AgentStatus: int {...'? Добавить 'as_lvalue'? –

ответ

5

ответ от Билла правильный ответ технически.

1) Другой подход

Другой способ сделать это, если вам нужно, чтобы избавиться от перечислений Несс типа, чтобы сделать тип уже сам по себе межд.

typedef int MyEnum; 
enum 
{ 
    CONST1 = 0, 
    etc... 
}; 

И тогда просто используйте его, как обычно. Компилятор не поймает плохие присваивания значений, но поскольку вы можете пометить все объявления как тип MyEnum, он должен быть достаточно простым, чтобы следить за тем, что происходит, и вы можете просто передать переменные где-нибудь, что говорит int.

2) Dangerous подход

НИКОГДА НЕ ЭТО!

EnumType v = EnumValue_... 

MyFunction(*((int*)&v)); 

ИЛИ ЭТО ...

#define MAKE_INT_REF(v) *((int*)&(v)) 

MyFunction(MAKE_INT_REF(v)); 

Причина в том, что компилятор может автоматически выбрать тип, используемый для перечисления. Он может выбрать int или он может выбрать char. Вы не можете быть уверены в разных компиляторах и платформах. Поэтому, если вы попробуете кастинг enum, вы получите неперехваченный код, а также очень опасный код, потому что запись на такой листинг может перезаписать другие значения.

+0

Будьте осторожны: в C++ 98 «enum» просто нужно подкрепить чем-то достаточно большим, чтобы удерживать его значения. Перечисление выше с 4 значениями может быть поддержано 'char', если это то, что компилятор хочет сделать. – Bill

+0

Правда. Поразмыслив, это очень плохая идея. Удаление этой части сейчас. – 2013-02-15 16:35:04

+0

Я решил преобразовать тип перечисления в int, как указано в 1) – Barth

8

Если у вас есть проблемы с рядный бросить это может быть полезно, чтобы разбить его на отдельной строке:

const AgentStatus enumValue = kRUNNING; 
... 
int intValue = static_cast<int>(enumValue); 
DimService("works now", intValue); 
+0

Нет ли другого способа, который не требует назначения 'intValue' обратно' enumValue'? – LogicStuff

+0

Поскольку перечисление может использовать любой базовый тип достаточного размера, вы не можете надежно использовать его для ссылочного параметра. Допустим, у вашего перечисления есть 4 элемента, и, таким образом, компилятор решает использовать 'char' внутренне. Как бы вы тогда взяли 'char &' и превратили его в 'int &' для аргумента функции? – Bill

+0

Будет ли это также плохой практикой, если я явно определяю базовый тип enum? – LogicStuff

Смежные вопросы