2017-03-02 142 views
1
struct student { 
    string name; 
    int age; 
}; 

int main() { 
    student a1; 

    cout << a1[0] << endl; //Access the first variable of the struct 
    cout << a2[1] << endl; //Access the first variable of the struct 
} 

我怎樣才能使用索引而不是使用「a1.name」從C++結構中訪問和檢索值?如何使用索引訪問C++結構屬性值?

+4

你不能。你爲什麼想做這個?如果你想要一個數組,使用一個數組。看起來像[XY問題](http://xyproblem.info/)。 –

+0

你不能在C++中做到這一點 – Sean

+0

如果語言允許......想象一下,如果你決定改變「學生」中成員的順序,那麼它會在你的程序中造成破壞。此外,這將是一個噩夢維持。你不能查找'a1 [0]'是否是名字或年齡,而不查找'struct'的定義。 –

回答

0

你不能。

直到在C++中引入反射,應該(我希望)是C++ 20中的情況。

Some projects介紹用名稱增強的元組,但它仍然不是真正的結構。

1

如何使用索引訪問C++結構屬性值?

你不行。 C++語言沒有這個功能。這可以用支持(靜態)反射的語言來實現。

您可以選擇使用std::tuple代替,該代碼允許索引成員訪問,但由於您無法命名成員,因此可讀性下降。

3

你不能。至少不是以你想要做的直接方式,而不是部分地重新定義結構是什麼。我將我的答案分成兩個部分的第一個解釋可能的方式得到至少接近你想要什麼,第二個解釋,你真正應該做的:

獲取下來,髒

有兩種方式(即我目前能拿出)這可能會給你一些思考:

  • 使用包裝類 - 而C++確實增加了結構的靈活性,它並不會改變他們的目的簡單的異構數據容器。但是,它確實允許操作員超載,包括[]操作員。因此,如果您創建一個包含結構作爲其成員的類(即它包裹結構),則可以使用[]公開結構的數據。這儘可能接近你想要做的事情。但是它確實會破壞使用結構體的全部目的,因爲你可以用簡單的非結實類成員來完成這個工作,但是我實際上在很久以前就已經看到了,當時我正在瀏覽一個C++庫,爲了提供更現代的功能而不需要完全重寫C代碼。
  • 使用偏移量指針 - 使用索引通常表明底層容器在涉及其包含的數據塊時具有一致性。問題是一個結構不一定遵守這個,因爲它可以包含(就像你的情況一樣)多種類型的數據。如果您可以犧牲結構的異質性並堅持使用單一數據類型(例如一個或多個雙精度),則可以安全地使用(直到必須始終記住結構具有的成員數量)指針以及訪問其成員的增加/減少的偏移量。就像創建標準引用(又名指針)時的任何類型的數據一樣,該引用指向該數據使用的內存開始地址。使用指針來遍歷數組是很常見的做法,它的工作方式就像這樣 - 創建一個對結構的引用,並添加+1,+2,...(與結構體中的許多成員一樣)。這使得事情過於複雜,並且容易出錯。如前所述,它還需要在結構中使用相同類型的數據。

替代...

從你給的信息,我認爲你正在尋找一個完全不同類型的數據 - 一本字典,地圖或列表包含某種自定義的通用數據容器可以容納任何類型的數據,但也可以存儲該數據的類型,以便將其重新設置爲原始狀態。許多庫提供這樣的容器,例如Qt的QVariant(核心模塊的一部分),boost有你的標準C++(自C++ 11以後)提供的boost::variantstd::tuple(或更好的命名元組),等等。我可以更詳細地談論Qt,因爲我有更多的經驗。它提供了QVariantListtypedefQList<QVariant>),它允許建立索引。當然,所有這些都需要你1)放棄你的結構,2)使用一些更高級的容器,這些容器可能會或可能不會在你正在做的任何事情上帶來巨大的缺點,包括許可問題,內存開銷,較大的二進制文件,處理大量的額外的庫文件等。

+0

如何命名元組?不如反思,但接近目標,沒有任何開銷(編譯時除外) –

+0

坦率地說,我從來沒有使用過命名的元組。從網上的簡短研究看來,這些是標準元組的更好的版本。所以是的,這應該是一個很好的解決方案。將編輯我的文章(我提到了元組,但現在也會添加指定版本)。謝謝! – rbaleksandar