如何创建一个不可变结构的std::数组?即只有const值的结构



假设我有结构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;

}


}

最新更新