循环 2 个 constexpr 数组对来实例化并运行模板函数

问题描述 投票:0回答:1

项目的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 数组(所有三元组、四元组...)吗?

c++ templates constexpr function-templates nested-for-loop
1个回答
0
投票

这是一个解决方案。我认为

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>();

}

演示

© www.soinside.com 2019 - 2024. All rights reserved.