簡體   English   中英

防止在C ++中構造/初始化數組元素

[英]Prevent construction/initialization of array elements in C++

我有以下聲明(是的,它使用運行時數組長度擴展名)

Iterator traversal_stack[depth]; 

我的問題是,編譯器嘗試初始化數組成員。 實際上,此代碼無法編譯,因為Iterator沒有公共默認構造函數。 雖然我了解了這種行為的根源,但在我看來,這確實是不希望的,因為對數組的訪問模式可確保:

  1. 一個數組元素最多將被寫入一次,
  2. 沒有元素就不會被讀取。

這種模式的任何違反都意味着算法混亂。 以下是說明如何使用數組的偽代碼(本質上是遍歷平衡樹的高度優化的堆棧)

Iterator traversal_stack[depth]; 
auto current_node = root;
auto current_level = 0;

// traverse the tree, looking for a suitable insertion point
// within every node, record visited nodes (vie the iterator struct)
while(current_level < depth) {
   // find the optimal insertion entry (pointed to by the iterator) 
   auto iter = as_branch(current_node).iterate();
   iter = find_best_insertion_point(iter, to_inserted_object);

   // record the visited node in the stack
   // a value is pushed onto the stack exactly  once!
   traversal_stack[current_level] = iter;

   // get to the next level of the tree
   current_node = iter.node_for_entry();
   current_level += 1;
}

// ... insert the data into the found terminal node

// now unroll the stack, adjusting the node metadata
current_level -= 1;
while(current_level >= 0) {
  // the element of the array is necessarily initialized
  // by assignment in the previous loop
  auto iter = traversal_stack[current_level];
  insertion_state = adjust_node_metadata_for(iter);

  current_level -= 1;
}

我知道我可以只提供默認構造函數並使用它,但是我真的很想避免使用它。 除了可能的(但可能不太重要)的性能考慮之外,默認構造函數的最大問題是,它必須引入某種默認的無效狀態,從而使迭代器的語義混亂不堪。

所以,我的問題是:我可以這樣聲明數組,使值完全未定義嗎? 如果解決方案特定於使用最新的C ++ 1z草稿+自定義擴展的Clang,我可以。

如果您真的要使用VLA和未初始化的對象。

一種方法是使用std :: aligned_storage創建未初始化的內存塊,然后將其強制轉換為對數組的引用。

#include <type_traits>

struct Iterator {
  Iterator() = default;
};

int main() {
  int length = 10;
  std::aligned_storage_t<sizeof(Iterator), alignof(Iterator)> memory_blocks[length];
  auto &array = reinterpret_cast<Iterator (&)[length]>(memory_blocks);

  return 0;
}

暫無
暫無

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

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