Const数组从其他Const数组初始化


const char DICTIONARY[][6] = {
"apple",
"sands"
};
class LetterSet {
public:
unsigned int bitfield;
LetterSet(const char letters[5]) {};
};
const LetterSet words[] = {
LetterSet(DICTIONARY[0]),
LetterSet(DICTIONARY[1]),
};

DICTIONARY太大而无法手动写出的情况下,我如何修改上面的代码?具体来说,我不知道如何以任何非运行时循环的方式初始化words数组并创建每个元素。

Carson可能不需要

,但对于那些想在编译时将数组元素转换为另一种类型的人来说,可以使用辅助模板和std::array。一个例子:

template<class T, std::size_t...Is>
auto transform_array_impl(auto&& array, std::index_sequence<Is...>)
{
return std::array<T, sizeof...(Is)>
{{
T(array[Is])...
}};
}
template<class T, class U, std::size_t N>
auto transform_array(const U (&array)[N])
{
return transform_array_impl<T>(array, std::make_index_sequence<N>());
}
const auto words = transform_array<LetterSet>(DICTIONARY);

在我看来,简单的解决方案是使用std::vector而不是数组。然后你可以在一行中进行初始化。

const std::vector<LetterSet> words(std::begin(DICTIONARY), std::end(DICTIONARY));

不知道如何对任意变量执行此操作,但在函数模板的上下文中,可以使用模板递归来构建此类参数:

template<typename T, std::size_t Pos = 0, std::size_t Size, typename F, typename ...Elements>
void makeArray(const F(&arr)[Size], const Elements&... elements) {
if constexpr(Pos < Size) {
makeArray<T, Pos + 1>(arr, elements..., arr[Pos]);
} else {
const T newArray[] { T(elements)... };
std::cout << sizeof(newArray) << std::endl;
}
}

您可以将其扩展到类成员,但不幸的是,这样的递归不太适用于构造函数,您将不得不处理一个自由的函数工厂(如果您不想提前指定所有模板参数,则命名构造函数习惯用法也不起作用(:

template<typename Type, std::size_t Size>
class my_class {
const Type array[Size];

template<typename... Elements>
my_class(const Elements&... elements): array{ elements... } {}

template<typename T, std::size_t Pos, std::size_t S, typename F, typename ...Elements>
friend my_class<T, S> makeMyClass(const F(&arr)[S], const Elements&... elements);

};
template<typename T, std::size_t Pos = 0, std::size_t S, typename F, typename ...Elements>
my_class<T, S> makeMyClass(const F(&arr)[S], const Elements&... elements) {
if constexpr(Pos < S) {
return makeMyClass<T, Pos + 1>(arr, elements..., arr[Pos]);
} else {
return my_class<T, S>{ elements... };
}
}

这就是从客户端代码来看的样子:

int main(){

const char DICTIONARY[][6] = {
"apple",
"sands"
};

const my_class instance = makeMyClass<LetterSet>(DICTIONARY);

return 0;
}

最新更新