[英]Prevent construction/initialization of array elements in C++
我有以下声明(是的,它使用运行时数组长度扩展名)
Iterator traversal_stack[depth];
我的问题是,编译器尝试初始化数组成员。 实际上,此代码无法编译,因为Iterator
没有公共默认构造函数。 虽然我了解了这种行为的根源,但在我看来,这确实是不希望的,因为对数组的访问模式可确保:
这种模式的任何违反都意味着算法混乱。 以下是说明如何使用数组的伪代码(本质上是遍历平衡树的高度优化的堆栈)
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.