Home > Software engineering >  about c templates and parameter pack
about c templates and parameter pack

Time:07-04

template<class... Cs>
void func(Cs... cs){
};
template<class T, class... Cs>

void func1(T s){

    func<Cs...>(/* the problem */);
};

int main(){
    char s[]="HI THERE!";
    func1<char*,char,char,char>(s);
    return 0;
}

so the func1() call the func(), the two functions are specialized by the same template parameter pack, the function func1() take a known parameter "s" and we assume that it can produce and provide the parameters values from that s to the func() , but how can we do that.

the problem is hard to me to explain i hope u get the point.

edit: lets say that the args that the func1() passes to func() follow this pattern s[0],s[1],... , is depend on the parameter pack actually

CodePudding user response:

If I understand it correctly, you want to use the parameter pack and expand those number of elements in s:

#include <cstddef>
#include <utility>

template<class... Cs>
void func(Cs&&... cs){ // 'H', 'I', ' '
};

template<class T, std::size_t... I>
void func1_helper(T s, std::index_sequence<I...>) {
    func(s[I]...);
}

template<class T, class... Cs>
void func1(T s){
    func1_helper(s, std::make_index_sequence<sizeof...(Cs)>{});
};

int main(){
    char s[]="HI THERE!";
    func1<char*, char,char,char>(s);
    return 0;
}

As you can see here, the actual types in the pack isn't needed. You could just as easily have supplied the number 3:

#include <cstddef>
#include <utility>

template<class... Cs>
void func(Cs&&... cs){ // 'H', 'I', ' '
};

template<class T, std::size_t... I>
void func1_helper(T s, std::index_sequence<I...>) {
    func(s[I]...);
}

template<std::size_t N, class T>
void func1(T s){
    func1_helper(s, std::make_index_sequence<N>{});
};

int main(){
    char s[]="HI THERE!";
    func1<3>(s);
    return 0;
}

If you really want to pass a pack of types that are not exact matches to what you've got in your array:

#include <cstddef>
#include <utility>
#include <iostream>

template<class... Cs>
void func(Cs... cs){ // 'H', 'I', ' '
    // prints HI and the `int` value of ' ' (32 most likely):
    (..., (std::cout << cs));
};

template<class... Cs, class T, std::size_t... I>
void func1_helper(T s, std::index_sequence<I...>) {
    func<Cs...>(s[I]...);
}

template<class T, class... Cs>
void func1(T s){
    func1_helper<Cs...>(s, std::make_index_sequence<sizeof...(Cs)>{});
};

int main(){
    char s[]="HI THERE!";
    func1<char*, char,char,int>(s);
    return 0;
}
  • std::make_index_sequence<sizeof...(Cs)>{} creates an object of type std::index_sequence<0, 1, 2> (in this case).
  • In func1_helper the indices, 0, 1, 2 goes into the parameter pack size_t... I to match the anonymous index_sequence<I...> argument.
  • I is then used to expand s[I]... into s[0], s[1], s[2].
  • Related