防止C 中阵列元素的构建/初始化
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草稿 自定义扩展的特定解决方案的,则可以。
如果您真的想使用VLA和非初始化对象。
一种方法是使用std :: aligned_storage来创建非初始化的内存块,然后将其施放为对数组的引用。
#include <type_traits>
struct Iterator {
Iterator() = delete;
};
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;
}
相关文章:
- 是否可以初始化不可复制类型的成员变量(或基类)
- C++使用整数的压缩数组初始化对象
- C++初始化基类
- 多成员Constexpr结构初始化
- 使用GCC 4.8构建错误:数组用作初始化器
- 在函数呼叫时,请从异质初始化列表中构建元组
- 如果初始化需要shared_from_this,如何在一次调用中构建一个类
- C++ 提升:在构建器之后初始化端点
- 如何使用由 PNG 数据构建的 blob 初始化 Magick::Image obj(PNG 由 cv::imencod
- 如何在成员初始化器列表中构建模板类的构造
- 为链接列表构建迭代器类(错误:无匹配的构造函数以初始化)
- 防止C 中阵列元素的构建/初始化
- 我如何避免明确构建C 初始化列表中继承的所有内容
- C++14 元编程:在编译/初始化时自动构建类型列表
- 干燥的方式来构建具有相同初始化器列表的数组的所有元素
- 有没有一种方法可以在不使用std ::移动的情况下初始化类构建类的类
- 构建矢量以允许非初始化的存储
- 静态初始化期间将 gcc 构建的 Boost 链接到英特尔 C++ 编译程序时出现 Segfault
- 为什么有时在vs2015中构建程序时出现"应用程序无法正确初始化(0xc0000018)"
- 如何使用资源获取初始化实现构建器模式