![](/img/trans.png)
[英]Why does the C++ standard specifically grant leeway regarding memory layout of class data members with different access specifiers?
[英]Does a class need to be a standard layout type to be sure of the memory offsets of its members?
可以說我想寫一個侵入式列表。 我有一個侵入式列表類模板,該模板帶有類型和指向成員的指針以用作節點。 大致如下所示:
// This needs to be a member of anything the intrusive list is going to store.
class IntrusiveListNode {
// ...
}
// The intrusive list itself
template <class T, IntrusiveListNode T::*Member>
class IntrusiveList {
// ...
};
// This is a type that is going to be stored in an intrusive list.
class IntegerListNode {
public:
IntrusiveListNode node;
private:
int value;
};
// An example of the how the list would be used.
IntrusiveList<IntegerListNode, &IntegerListNode::node> myList;
您要存儲在列表中的每件事物上都有一個IntrusiveListNode。 要將IntrusiveListNode轉換成可以使用的東西,例如IntegerListNode,您可以調用一個函數,該函數根據節點在類中的偏移量對節點執行一些指針運算,然后將其強制轉換為適當的類型。 這似乎可行,但我認為不能保證。
我希望能夠在我的類中添加一個static_assert,以便在編譯時驗證您所使用的類型是安全的,但是我不確定static_assert的條件是什么。 我認為只有在保存IntrusiveListNode的類型是標准布局類的情況下才能保證工作,但是我不確定,因為對標准布局類型的要求似乎比我實際需要的要嚴格。
特別是,標准布局類型要求所有成員都具有相同的訪問控制。 我需要的只是能夠確保指針算法能夠正常工作。 那將意味着您不能在多態類型上使用它,因為該結構的兩個不同版本可能會以不同的方式進行布局,但是如果該類型包含私有數據成員和公共數據成員的某種混合,這不應該成為問題,對嗎? 如果我只要求類型是非多態的,那會安全嗎? 還是有更好的檢查方法? 還是我堅持進行is_standard_layout
檢查?
我不能在此引用標准(而且我很確定這是未定義的行為),但是您可以通常依靠數據成員相對於包含類的指針的偏移量的一致性。該指針的類型是常量(在您的情況下為IntegerListNode *)。
您可能會發現偏移量相對於指向派生類型的指針進行測量時會發生變化,但是只要您始終始終首先將Ininterpret_cast轉換為IntegerListNode,然后再將其靜態/動態轉換為派生類型(如果需要),我幾乎會感到滿意:)
這並不是說這是一個好主意。 實現侵入式列表不需要這種指針算法。 如果您僅在IntegerListNode中定義“下一個”和/或“上一個”指針(指向IntegerListNode),則可以將指向該成員的指針傳遞給IntrusiveList,並且永遠不需要創意轉換:)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.