例如:
struct thing1 {
int very_important_integer = 5;
};
struct thing2 {
thing1 &thing;
thing2(thing1 &A) : thing(A) {}
};
int main() {
// in practice, this array is 49,500 elements large, not just 5
thing1 stuff[5]; // OK
thing2 arr[5]; // error: no default constructor for thing2
}
我无法向
thing2
添加默认构造函数,因为有一个要初始化的引用。
不确定这是否是您想要的,但这是唯一的选择 - 在创建时初始化元素。
struct thing1 {
int veryimportantinteger = 5;
};
struct thing2 {
thing1& thing;
thing2(thing1& A) : thing(A) {}
};
int main() {
thing1 stuff[5];
thing2 arr[5]{stuff[0], stuff[1], stuff[2], stuff[3], stuff[4]};
}
带有指针的示例
struct thing2 {
thing1* thing{};
thing2() = default;
thing2(thing1& A) : thing(&A) {}
};
int main() {
thing1 stuff[5];
thing2 arr[5]{};
for (size_t i = 0; i < std::min(std::size(arr), std::size(stuff)); ++i)
arr[i] = stuff[i];
}
您可以使用
placement-new
来构造 arr[]
的数组元素,从而允许您在每个元素上调用 thing2
构造函数,即在循环中:
struct thing1{
int veryimportantinteger = 5;
};
struct thing2{
thing1 &thing;
thing2(thing1 &A):thing(A){}
};
int main(){
thing1 stuff[5];
char buffer[sizeof(thing1)*5];
thing2 *arr = reinterpret_cast<thing2*>(buffer);
for (int i = 0; i < 5; ++i){
new (&arr[i]) thing2(stuff[i]);
}
//use arr as needed...
for (int i = 0; i < 5; ++i){
arr[i].~thing2();
}
}
在现代 C++ 中,您应该使用
std::aligned_storage
/alignas
、std::launder
、std::construct_at()
/std::destroy()
等来使代码更安全/正确,但基本原则仍然存在 - 预先分配一个足够大小的缓冲区,在缓冲区中适当的偏移处放置构造每个对象,根据需要使用对象,然后在使用完缓冲区后销毁它们。
如果您将 c-array 更改为
std::array
,您可以创建一个函数来创建数组:
// const variant omitted.
// C++20
template <typename T, std::size_t N, typename From>
std::array<T, N> make_array_from(std::array<From, N>& froms) {
return [&]<std::size_t... Is>(std::index_sequence<Is...>) {
return std::array<T, N>{{T{froms[Is]}...}};
}(std::make_index_sequence<N>());
}
// C++17
template <typename T, std::size_t N, typename From, std::size_t... Is>
std::array<T, N> make_array_from_impl(std::index_sequence<Is...>, std::array<From, N>& froms) {
return std::array<T, N>{{T{froms[Is]}...}};
}
template <typename T, std::size_t N, typename From>
std::array<T, N> make_array_from(std::array<From, N>& froms) {
return make_array_from_impl(std::make_index_sequence<N>(), froms);
}
随着使用
std::array<thing1, 5> stuff{/*..*/};
auto arr = make_array_from<thing2>(stuff);