我们考虑一个具有构造函数和成员函数A
的类foo
。
以下是一些代码:
constexpr int size1 = 100;
constexpr int size2 = 13;
constexpr int size3 = 48;
constexpr int size4 = 231;
constexpr int size5 = 5;
constexpr int size6 = 125;
constexpr int size7 = 88;
constexpr int size8 = 549;
constexpr int size9 = 417;
int main(void)
{
std::array<A*, size1> array1;
std::array<A*, size2> array2;
std::array<A*, size3> array3;
std::array<A*, size4> array4;
std::array<A*, size5> array5;
std::array<A*, size6> array6;
std::array<A*, size7> array7;
std::array<A*, size8> array8;
std::array<A*, size9> array9;
// Solution
return 0;
}
我想构造每个数组的每个元素,然后为每个数组调用成员函数foo
。
基本上,我想这样做:
for (auto& element : array1)
{
element = new A();
element->foo();
}
每个数组。
最简单快捷的方法是什么,而不必连续写下9个for循环?
答案 0 :(得分:2)
您可能会做类似的事情:
template <std::size_t N>
using As = std::array<A*, N>;
std::tuple<As<size1>, As<size2>, As<size3>, As<size4>, As<size5>,
As<size6>, As<size7>, As<size8>, As<size9>> arrays;
std::apply([](auto& ...as)
{
auto l = [](auto& a)
{
for (auto& element : a)
{
element = new A();
element->foo();
}
};
(l(as), ...);
}, arrays);
或更简单:
template <size_t N>
std::array<A*, N> MakeAs()
{
std::array<A*, N> res;
for (auto& element : res)
{
element = new A();
element->foo();
}
return res;
}
和
auto array1 = MakeAs<size1>();
auto array2 = MakeAs<size2>();
auto array3 = MakeAs<size3>();
auto array4 = MakeAs<size4>();
auto array5 = MakeAs<size5>();
auto array6 = MakeAs<size6>();
auto array7 = MakeAs<size7>();
auto array8 = MakeAs<size8>();
auto array9 = MakeAs<size9>();
答案 1 :(得分:2)
您很可能希望将代码打包到特定的初始化函数中。由于长度不同的(std::
)数组实际上是不同的类型,因此,您要么需要模板函数,要么需要对数组的内部原始数组(data()
)进行操作:
template <typename T>
void initialize(T& t)
{
for(auto& a : t)
// ^ reference to pointer (!)
{
a = new A();
a->foo();
}
std::cout << std::endl;
}
然后您只需在每个数组上调用此函数。如果还不够短,您可以将其打包到可变参数模板函数中:
template <typename T, typename ... TT>
void initialize(T& t, TT& ... tt)
{
initialize(t);
initialize(tt...);
}
// alternatively, a bit shorter, with C++17 fold expression:
template <typename ... TT>
void initialize(TT& ... tt)
{
(initialize(tt), ...);
}
在通话时,这很可能是您能获得的最短的时间(除了选择一个更短的名称之外):
initialize(array1, array2, array3, array4, ...);
答案 2 :(得分:1)
//C++ 11 SFINAE fold
template<size_t I = 0, typename F, typename ...Ts>
typename std::enable_if<I == sizeof...(Ts)>::type //I == end
for_each(std::tuple<Ts...>&, const F&) {}
template<size_t I = 0, typename F, typename ...Ts>
typename std::enable_if<I < sizeof...(Ts)>::type //I < end
for_each(std::tuple<Ts...>& tuple, const F& function)
{
function(std::get<I>(tuple));
for_each<I + 1>(tuple, function);
}
//C++ 17
template<size_t I = 0, typename F, typename ...Ts>
void for_each(std::tuple<Ts...>& tuple, const F& function)
{
if constexpr(I < sizeof...(Ts))
{
function(std::get<I>(tuple));
for_each<I + 1>(tuple, function);
}
}
//Client
for_each(std::tie(array1, array2, array3, array4, array5, array6, array7, array8, array9),
[](auto& array)
{
for(auto* element : array)
{
element = new A();
element->foo();
}
});