假设我有结构S:
struct S {
const int i;
const bool b;
}
我想创建这个结构的(非常数(数组,如下所示:
std::array<S, 16> arr;
for(int i = 0; i<arr.size(); i++)
arr[i] = { i, i%2==0 };
然后编译器会抱怨我在初始化数组时没有初始化a常量变量。
我试着用一个向量作为中介。但是在我正在编写的函数中,我必须将原始数组传递到另一个结构中,并返回另一个构造。
struct OtherStruct {
const std::array<S,16> sArray;
};
OtherStruct f() {
std::vector<S> vec(16);
for(int i = 0; i<16; i++)
vec.push_back({ i, i%2==0 });
return { vec.data() };
}
但这也没用。我希望传递到矢量数据的指针将被转换为C样式的数组,从中可以生成std::数组。解决这个问题最干净的方法是什么?
我正在使用C++11。
请注意,此示例是一个粗略的简化。线路arr[i] = { i, i%2==0 };
将被解析传入网络数据的函数所取代。实际的数组要大得多,结构也更复杂。在编译时,将填充结构的所有数据都不为人所知,只有布局。
您可以使用参数包扩展来创建任意大小的初始化程序列表。
您需要将std::index_sequence
备份到C++11
template <size_t... Is>
std::array<S, sizeof...(Is)> make_s_array_impl(index_sequence<Is...>) {
return { { { Is, Is % 2 == 0 }... } };
}
template <size_t N>
std::array<S, N> make_s_array()
{
return make_s_array_impl(make_index_sequence<N>{});
}
实时查看
由于在编译时已知值的数量,因此可以使用初始值设定项列表填充数组。您可以使用BOOST_PP_REPEAT
:轻松创建它
#include <boost/preprocessor/repetition/repeat.hpp>
struct S {
const int i;
const bool b;
};
struct OtherStruct {
const std::array<S,16> sArray;
};
OtherStruct f() {
#define FILL(z, i, ignored) { i, i%2==0 },
return {std::array<S,16>{{
BOOST_PP_REPEAT(16, FILL, ignored)
}}};
#undef FILL
}
在C/C++中,当您使用const
关键字时,您不能在声明变量时使其未初始化,也不能在声明后分配新值。
例如:
const int i = 5; //this is a correct way to use the const keyword
const int i;
...
i = 5; //this is NOT a correct way to use the const keyword
但是,可以使用const_cast<T>
将相同类型的指针绑定到结构实例的值,并在for循环中只更改一次。
这样你就可以得到你所要求的。
#include <iostream>
#include <array>
struct S{
const bool b = 0; //Intialize the values in order to avoid compiler errors.
const int i = 0;
};
int main(){
std::array<struct S, 16> arr;
for(int i = 0; i<arr.size(); i++){
// declare a variable that point to the const value of your struct instance.
bool* b = const_cast <bool*> (&arr[i].b);
int* in = const_cast <int*> (&arr[i].i);
*b = i; //change the value with the value you need.
*in = i%2==0;
}
for(int i = 0; i<arr.size(); i++){
int a = i%2==0;
std::cout<< "const bool: " << arr[i].b << " " << (bool)i << "const int: " << arr[i].i << " " << a << std::endl;
}
}