2015-04-24 18 views
1

我問這個問題:Array Equivalent of Bare-StringINT *到常量數組

這個問題的答案是C++沒有爲const int*小號提供此功能。這令人失望。所以我的問題是:在實踐中,我如何解決這個限制?

我想寫這樣一個結構:

struct foo{ 
    const char* letters = "abc"; 
    const int* numbers = ??? 
}; 

我不能:

  1. &{1, 2, 3},因爲我不能拿的r值
  2. array<int, 3>{{1, 2, 3}}.data()事業的地址內存在初始化後立即清理
  3. const int* bar(){ return new int[3]{1, 2, 3}; }因爲什麼都不會刪除這個指針

我知道我可以使用自動指針來解決這個問題。我不是說struct foo是好代碼,我想說明編譯器提供了將常量數組​​存儲在內存中並在程序退出時清理它,我想要有一種方法可以做到這一點int s以及。

有沒有辦法做到這一點?

+0

考慮你沒有把一個'C'標籤對於這個問題,我建議使它一個類並選擇選項3. – user3528438

+0

使用'const int numbers [] = {1,2,3}'有什麼問題;'? – NathanOliver

+0

@ user3528438正如問題所述:「我並不是建議struct foo是很好的代碼......我希望有一種方法可以爲整數提供這種方法。」問題不在於如何編寫'foo'。 –

回答

6

你如何指向一個靜態 - 我認爲這是什麼編譯器幾乎在內部爲"strings literals"呢?

static const int Numbers[] = {1, 2, 3}; 

struct foo{ 
    const char* letters = "abc"; 
    const int* numbers = Numbers; 
}; 
+0

我喜歡它,我不知道爲什麼我沒有想到這一點。 –

+0

@Reader我有一個解決方案基於[Ben Voigt](http://stackoverflow.com/users/103167/ben-voigt)的答案:http://stackoverflow.com/a/29850546/2642059但是,應該由於答案中提到的兩個缺點,不能被認爲是一個客廳的伎倆。這個答案唯一的缺點是可以通過使用匿名命名空間來消除命名空間污染。使用這種策略,這是正確的答案。 –

2

字符串文字是你所得到的。但是,它們也足以覆蓋大部分積分數據。在你的情況下,你可以使用

L"\1\2\3" 

得到一個由編譯器管理的寬字符數組。 C++ 11及更高版本還支持u8,u16u32字符串。

+0

C++中保證'wchar_t'與'int'的大小相同嗎?如果不是,這是一個問題嗎? – user2079303

+0

@ user2079303:不,不能保證。在Win32上,它永遠不會。儘管如此,您仍然可以將不重要的數據存儲在字符串文字中。 –

+0

@BenVoigt嗯......這是'L'種類的操作符嗎?好像我可以在編譯時使用模板正確地決定類型和字符串字符大小? –

1

我們可以做到這一點使用Ben Voigt的回答是:

const int* numbers = sizeof(int) == sizeof(char32_t) ? reinterpret_cast<const int*>(U"\1\2\3") : reinterpret_cast<const int*>(u"\1\2\3"); 

三元是編出來的是事實,你可以聲明numbersconstexpr證明。

有幾個缺點,此實現:

  1. 這實際上是一個wchar_t字符串文字,你會得到除了任何字符終止0元素指定
  2. 這假定一個int會無論是32位或16位,如果不是這種情況,這將嘗試從char16_t到任何大小int投,你將有重大問題

在任何情況下,我們可以簡化這一成宏:

#define QUOTATION(x) sizeof(int) == sizeof(char32_t) ? reinterpret_cast<const int*>(U ## x) : reinterpret_cast<const int*>(u ## x) 

哪些可以像使用:

const int* numbers = QUOTATION("\1\2\3");