C++ 如何在不硬编码数组的情况下初始化类的初始值设定项列表中的std::数组';s码
我有一个Foo.h:C++ 如何在不硬编码数组的情况下初始化类的初始值设定项列表中的std::数组';s码,c++,arrays,C++,Arrays,我有一个Foo.h: #include <array> class Bar { public: Bar(std::string name) : name(name) {} std::string name; }; class Foo { public: enum {ARRAY_SIZE=10}; Foo(); void printElement(int idx); std::array<Bar,ARRAY_SIZE> myArray;
#include <array>
class Bar {
public:
Bar(std::string name) : name(name) {}
std::string name;
};
class Foo {
public:
enum {ARRAY_SIZE=10};
Foo();
void printElement(int idx);
std::array<Bar,ARRAY_SIZE> myArray;
};
最好的方法是什么
顺便说一下,我正在使用g++6.3.0 使用辅助函数。加
template <std::size_t N>
auto make_array()
{
std::array<Bar, N> arr;
for (std::size_t i = 0; i < N; ++i)
arr[i] = std::to_string(N - i - 1);
return arr;
}
使用辅助函数。加
template <std::size_t N>
auto make_array()
{
std::array<Bar, N> arr;
for (std::size_t i = 0; i < N; ++i)
arr[i] = std::to_string(N - i - 1);
return arr;
}
声明myarray时,它具有“正确的大小”(即数组大小)。也就是说,您不需要初始化std::array来给它一个大小。大小是数组类型的一部分。数组大小是否总是固定的?为什么不把它作为模板参数?@Jasancos:这个网站有编辑历史;更新问题时,不需要保留旧版本。这只会让新的读者感到困惑。当您声明myarray时,它的大小是“正确的”(即ARRAY_size)。也就是说,您不需要初始化std::array来给它一个大小。大小是数组类型的一部分。数组大小是否总是固定的?为什么不把它作为模板参数?@Jasancos:这个网站有编辑历史;更新问题时,不需要保留旧版本。这让新读者感到困惑。非常感谢您提供的解决方案,但我最初的示例并没有描述我的问题。我已经编辑了这个问题accordingly@Jasancos没问题。我已经更新了答案,以便为
Bar
工作,如果您想要Bar(“九”)
,Bar(“八”)
等,您将需要第二个助手函数,而不是std::to_string
,但这确实是正确的解决方案。@Jasancos没有。该函数的工作原理类似于std::declval
的工作原理。它的存在只是为了得到一个可以使用的类型。这是一种模板元编程技术。@Jasancos如果你能使用C++17,代码将编译成CTAD(类模板参数解析)。如果不能使用C++17,则需要返回std::array{Bar{std::to_string(Is)}…}代码>非常感谢您提供的解决方案,但我最初的示例没有描述我的问题。我已经编辑了这个问题accordingly@Jasancos没问题。我已经更新了答案,以便为Bar
工作,如果您想要Bar(“九”)
,Bar(“八”)
等,您将需要第二个助手函数,而不是std::to_string
,但这确实是正确的解决方案。@Jasancos没有。该函数的工作原理类似于std::declval
的工作原理。它的存在只是为了得到一个可以使用的类型。这是一种模板元编程技术。@Jasancos如果你能使用C++17,代码将编译成CTAD(类模板参数解析)。如果不能使用C++17,则需要返回std::array{Bar{std::to_string(Is)}…}代码>
template <std::size_t N>
auto make_array()
{
std::array<Bar, N> arr;
for (std::size_t i = 0; i < N; ++i)
arr[i] = std::to_string(N - i - 1);
return arr;
}
Foo::Foo(): myArray(make_array<10>()) {}
// helpers for reversing an integer sequence
template <std::size_t ... Is>
constexpr auto indexSequenceReverse (std::index_sequence<Is...> const &)
-> decltype( std::index_sequence<sizeof...(Is)-1U-Is...>{} );
template <std::size_t N>
using makeIndexSequenceReverse
= decltype(indexSequenceReverse(std::make_index_sequence<N>{}));
class Bar {
public:
Bar(std::string name) : name(name) {}
std::string name;
};
class Foo {
public:
enum {ARRAY_SIZE=10};
Foo();
void printElement(int idx);
std::array<Bar,ARRAY_SIZE> myArray;
// get sequence and expand out initializes
template <std::size_t ... Is>
auto make_array_impl(std::integer_sequence<size_t, Is...>)
{
return std::array{ Bar{std::to_string(Is)}... };
}
// convenient forwarder to implementation
template <std::size_t N>
auto make_array()
{
return make_array_impl(makeIndexSequenceReverse<N>{});
}
};
Foo::Foo(): myArray(make_array<10>()) {}
void Foo::printElement(int idx) {
if (idx < ARRAY_SIZE) {
std::cout << "Value is " << myArray[idx].name << std::endl;
} else {
std::cout << "Index out of bounds" << std::endl;
}
}
int main() {
Foo foo;
foo.printElement(1);
}