2013-10-23 78 views
1

是否有一種簡單的方式來通過成員跨越結構的STL向量?換句話說,如果我有這樣一個結構:跨越結構向量的成員

struct foo { 
    double x, y, z; 
}; 

在載體std::vector<foo> bar(20),我可以跨越所述陣列從各結構挑選出X步幅?

我已經試過這一點,但它似乎不工作:

for (int i=0; i<20; ++i) 
{ 
    double xx = (&bar[0].x + i*sizeof(bar[0]))->x; 
} 

爲什麼不工作? sizeof(bar[0])沒有考慮結構之間的填充嗎?

注意:我意識到這是一個非常愚蠢的方式來訪問一個循環中的x,但這個循環只是一個實驗,看看跨步是否奏效。

如果有幫助,我想這樣做,這樣我就可以將bar傳遞給庫例程,它接受一個指針和一個stride作爲構造函數參數到它自己的內部數據類型。當然,我可以將我的代碼從AoS轉換爲SoA,但除非必須,否則我不想那樣做。

+1

sizeof將不包含填充,因爲填充可以取決於數據結構之前和之後的內容。 你也許可以用「int size =(char *)&bar [1] - (char *)&bar [0]」來代替?不知道這是多麼合法,但這是爲什麼這是一個評論,而不是一個答案。 – jcoder

+0

每當我看到「聰明」的東西時,我都想知道爲什麼有人會想要做些什麼 - 更隱晦和無法維護。 – Chad

+0

再一次,我真的需要開始和大步走到我無法控制的第三方圖書館。循環只是一個經驗性的測試,以確認它的工作原理,而不是試圖變得聰明。 – Fadecomic

回答

1

我想我會計算步幅,而不是直接使用類似:

struct point { 
    double x, y, z; 
}; 

int main() { 
    point points[2]; 

    std::cout << "stride = " << (char *)(&(points[1].x)) - (char *)(&(points[0].x)) << "\n"; 
} 
1

&bar[0].x是指向翻一番。您正在向其添加i*sizeof(bar[0])

其效果是存儲在指針中的地址增加i*sizeof(bar[0])*sizeof(double)這不是你所期望的。

正確的表達是

&bar[0].x + i*sizeof(bar[0])/sizeof(double) 
+0

雖然'bar'有一個「double」成員,但標準允許的'sizeof(bar)'不可能是'sizeof(double)'的倍數。當然,對於這個特殊的班級來說尤其不可能,因爲它沒有不是「雙」的成員。 –

0

&巴[0] .X是指向翻一番。要添加適當的班次,您需要將其轉換爲char *,然後再次double *。

 double xx = *reinterpret_cast<double*>(reinterpret_cast<char*>(&bar[0].x) + i*sizeof(bar[0])); 

在任何情況下,您都應該考慮使用標準算法來達到您的目的。

+0

我需要步幅和初始指針作爲第三方庫的參數。這真的是我追求的步幅(和最初的指針)。這個循環只是一個經驗性的測試。 – Fadecomic

+1

好的。然後它就在這裏:步幅很簡單,就是'sizeof(foo)',不需要算術運算。你可以從'reinterpret_cast (&bar [0] .x)'開始。我個人喜歡使用'reinterpret_cast'。它在這裏清楚地宣傳我們正在處理非標準,低級別的技術。 – user1735003

+0

如何填充? sizeof(foo)是我嘗試的第一件事,它不起作用,因此對sizeof(bar [0])進行了更改。 – Fadecomic