簡體   English   中英

scanf()與C ++枚舉

[英]scanf() with C++ enums

以下是我們的代碼庫中的典型情況。

enum ConfigOption { CONFIG_1=1, CONFIG_2=2, CONFIG_3=3 }

ConfigOption cfg1, cfg2;

sscanf(s, "%d", &cfg1);

這是一個內部使用的仿真軟件。 沒有分發。 易於維護和正確性非常重要。 可移植性和用戶界面 - 不是真的。

問題是c ++中的enum不一定是int 因此,我們會收到編譯器警告,並且在使用其他編譯器或啟用優化時可能會出現錯誤行為。

一種解決方案就是將&cfgint* 但是,這不會捕獲編譯器決定在enum分配int以外的東西的情況。

所以我提出了以下解決方案:

template<typename T> inline
int& eint(T& enum_var) {
    assert(sizeof(T) == sizeof(int));
    return (int&)enum_var;
}

現在使用scanf如下:

sscanf(s, "%d", &eint(cfg1));

我很想聽聽上述問題的意見和其他(更好的)解決方案。 請記住,其中一個目標是保持代碼簡單。 這不是“生產質量”的東西,你添加的越多 - 維護就越困難。

如果你有像vs2010這樣的現代編譯器,你可以指定枚舉元素的大小

enum class ConfigOption: unsigned int {CONFIG_1=1, CONFIG_2=2, CONFIG_3=3};

它在C ++ 0x中的新功能

我的解決方案是將枚舉強制到最小尺寸。這就是微軟在他們的DirectX頭文件中為他們的枚舉所做的事情(我不得不承認這是一個很好的技巧)。

他們通過添加如下虛擬枚舉來強制枚舉的大小等於int:

typedef enum 
{
  fooo = 1,
  baar = 2,
  ___Force32Bit = ~0UL
} MyEnum;

現在枚舉總是至少是int的大小。

如果你願意,你可以把它放在頂部..這個強迫enum的大小很長:

typedef enum 
{
  fooo = 1,
  baar = 2,
  ___Force64Bit = ~0ULL
} MyEnum;

我知道,這不是一個超級干凈的解決方案。 我認為這樣的解決方案不存在,並且到目前為止,強制執行最小尺寸對我來說效果很好。 如果你從32位到64位代碼,你可能需要調整代碼,但通常在這些情況下你必須檢查代碼的某些部分,所以沒有大問題。

順便說一句 - 對不起C代碼,我知道這個問題被標記為C ++,但我是C-guys :-)

為什么不把它作為一個實際的int讀取?

enum ConfigOption { CONFIG_1=1, CONFIG_2=2, CONFIG_3=3 };
ConfigOption cfg1;

int i;
sscanf(s, "%d", &i);
cfg1 = i;

這樣你就可以進行更全面的有效性檢查(例如測試讀取整數是否在你的enum類型范圍內)。

(當然,如果您一直擔心檢測錯誤,對於這樣的簡單解析,您應該使用strtolstrtoul而不是sscanf 。)

您可以嘗試使用boost::lexical_cast ,或者如果您不使用boost並且不想在這種情況下開始使用它,您可以自己編寫一個簡化版本。 舉個例子來看看這個SO答案

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM