项目的C++版本是20。
假设我们有一些服务类模板:
template<int someSegmentSize>
class SomeAbstractFileService {
public:
void init() {
std::cout << "Initializing FileService with segment size: " << someSegmentSize << std::endl;
}
template<int HashNum>
void create_shemas() {
std::cout << "Creating with hash function number: " << HashNum << " and segment size: " << someSegmentSize << std::endl;
}
//some other non template functions ...
};
和 2 个 constexpr 数组(当前填充任意值):
constexpr size_t N=7;
constexpr size_t N2=7;//sizes may differ
constexpr std::array<int,N> segment_size_arr{-1, -2, -3, -4, -5, -6, -7};
constexpr std::array<int,N2> hash_num_arr{1, 2, 3, 4, 5, 6, 7};
出于测试目的,我想迭代两个数组的所有值对(例如 (-1,1),(-1,2),...,(-1,7),(-2,1), ...,(-7,7)) 实例化并调用此函数模板:
template<int SegmentSize,int Hash>
void performStuff()
{
std::cout<<SegmentSize<<'\t'<<Hash<<'\n';
SomeAbstractFileService<SegmentSize> ss;
ss.init();
ss.template create_shemas<Hash>();//this function must be called with new object of SomeAbstractFileService otherwise schema update will collide with existing one
}
这是我使用折叠和 lambda 表达式的尝试之一(受到解决方案的启发):
#include<iostream>
#include<array>
template<int someSegmentSize>
class SomeAbstractFileService {
public:
void init() {
std::cout << "Initializing FileService with segment size: " << someSegmentSize << std::endl;
}
template<int HashNum>
void create_shemas() {
std::cout << "Creating with hash function number: " << HashNum << " and segment size: " << someSegmentSize << std::endl;
}
//some other non template functions ...
};
template<int SegmentSize,int Hash>
void performStuff()
{
std::cout<<SegmentSize<<'\t'<<Hash<<'\n';
SomeAbstractFileService<SegmentSize> ss;
ss.init();
ss.template create_shemas<Hash>();
}
template<typename T,size_t N,size_t N2,const std::array<T,N> segment_size_arr,const std::array<T,N2> hash_num_arr>
constexpr void iterate_pairs() {
[]<std::size_t... Is>(std::index_sequence<Is...> is) {
(([]<std::size_t val,std::size_t... Is2>(std::index_sequence<Is...> is,std::index_sequence<Is2...> is2)
{
constexpr T segsize=segment_size_arr[val];//some caveman check
(performStuff<segment_size_arr[val],hash_num_arr[Is2]>(),...);
}<Is>(is,std::make_index_sequence<N2>{})),...);
}(std::make_index_sequence<N>{});
}
int main(){
constexpr size_t N=7;
constexpr size_t N2=7;//sizes may differ
constexpr std::array<int,N> segment_size_arr{-1, -2, -3, -4, -5, -6, -7};//actually may be global variable
constexpr std::array<int,N2> hash_num_arr{1, 2, 3, 4, 5, 6, 7};//actually may be global variable
iterate_pairs<int, N, N2, segment_size_arr, hash_num_arr>();
}
但这会导致错误:
Invalid operands to binary expression ('(lambda at /.../main.cpp:39:11)' and 'unsigned long') main2.cpp:35:5: note: in instantiation of function template specialization 'iterate_pairs()::(anonymous class)::operator()<0UL, 1UL, 2UL, 3UL, 4UL, 5UL, 6UL>' requested here main2.cpp:58:5: note: in instantiation of function template specialization 'iterate_pairs<int, 7UL, 7UL, std::array<int, 7UL>{{-1, -2, -3, -4, -5, -6, -7}}, std::array<int, 7UL>{{1, 2, 3, 4, 5, 6, 7}}>' requested here
执行此类迭代的正确方法是什么?这个可以推广到任意数量的 constexpr 数组(所有三元组、四元组...)吗?
这是一个解决方案。我认为
iterate_pairs
不需要两个 lambda,一个就足以获取用于两个数组的每一项的索引。
#include<iostream>
#include<array>
#include<iostream>
template<int someSegmentSize>
class SomeAbstractFileService {
public:
void init() {
std::cout << "Initializing FileService with segment size: " << someSegmentSize << std::endl;
}
template<int HashNum>
void create_shemas() {
std::cout << "Creating with hash function number: " << HashNum << " and segment size: " << someSegmentSize << std::endl;
}
//some other non template functions ...
};
template<int SegmentSize,int Hash>
void performStuff()
{
std::cout<<SegmentSize<<'\t'<<Hash<<'\n';
SomeAbstractFileService<SegmentSize> ss;
ss.init();
ss.template create_shemas<Hash>();
}
template<typename T,size_t N,size_t N2,const std::array<T,N> segment_size_arr,const std::array<T,N2> hash_num_arr>
constexpr void iterate_pairs()
{
[]<std::size_t... Is>(std::index_sequence<Is...>)
{
(performStuff<segment_size_arr[Is],hash_num_arr[Is]>(),...);
}(std::make_index_sequence<N>{});
}
int main(){
constexpr size_t N=7;
constexpr size_t N2=7;//sizes may differ
constexpr std::array<int,N> segment_size_arr{-1, -2, -3, -4, -5, -6, -7}; //actually may be global variable
constexpr std::array<int,N2> hash_num_arr { 1, 2, 3, 4, 5, 6, 7}; //actually may be global variable
iterate_pairs<int, N, N2, segment_size_arr, hash_num_arr>();
}