0
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

joudia
  • 65
  • 5
  • 2
    What do you expect the arguments to the `func` call to be, in this specific case? `s[0]`, `s[1]` and `s[2]`? What if `T` is some other type? – user17732522 Jul 03 '22 at 15:14
  • 1
    It is not clear what output you expect from the program. Provide your expected output in the question. – Jason Jul 03 '22 at 15:16
  • @user17732522 it's depend on the parameter pack , if it is `````` it's ```s[0]```,```s[1]``` , if it is `````` its would be ```s[0]```,```s[1]```,```s[2]``` and so on , that the problem actual who to passe those args to ```func()``` . – joudia Jul 03 '22 at 15:19
  • `func1` needs to be `void func1(T s, Cs... cs)` and then you can forward those arguments to `func`. – Goswin von Brederlow Jul 03 '22 at 16:46
  • we assume we can get the args values from ```s``` so we dont need passe them to the ```func1()``` . – joudia Jul 03 '22 at 16:54
  • @HestiaGaia well, you can't simply **assume** it, please show how you'd like to actually get those out of `s`.(for example, you show you want an `int` in the chat in the answer, [link](https://chat.stackoverflow.com/transcript/message/54857277#54857277), which is not matching this post) – apple apple Jul 03 '22 at 16:56
  • lets say that s is a ```struct{ int n; char c, bool f }``` and we get them from the struct like s.a or s->a ... .the point is that we can get them for sure. – joudia Jul 03 '22 at 17:00
  • @HestiaGaia sorry then it wouldn't work here. it's not how template work. (at least without customized traits/getters) – apple apple Jul 03 '22 at 17:01
  • further explanation please – joudia Jul 03 '22 at 17:04
  • @HestiaGaia for example considering your existing 2 example. how the template knows you want `s.n` or `s[0]`? (how it even know it need to access `n` and not `m`) – apple apple Jul 03 '22 at 17:06
  • if it's customized for each type... well then simply use overloads of functions. – apple apple Jul 03 '22 at 17:07

1 Answers1

5

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].
Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108
  • @TedLyngmo i kinda undestand the solotion here i guess ( im not quoit familiar with the usage of index_sequence but i ve got the point ), but i have a question: what if the T s [ char* ] will expand to not [char,char,....] but is something like [char,int,...], – joudia Jul 03 '22 at 16:02
  • @HestiaGaia No, it will expand to `char, char, char` or `char&,char&,char&` in my example since I used forwarding references. [Example](https://godbolt.org/z/TT3EnTKT6) – Ted Lyngmo Jul 03 '22 at 16:02
  • @TedLyngmo but what if we want something like this : https://ibb.co/r4KS2ck – joudia Jul 03 '22 at 16:10
  • @HestiaGaia Please, no pictures. Use https://godbolt.org/ or some other online compiler please. – Ted Lyngmo Jul 03 '22 at 16:12
  • @TedLyngmo https://godbolt.org/z/99K6jY4vc here we go . – joudia Jul 03 '22 at 16:17
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/246134/discussion-between-hestiagaia-and-ted-lyngmo). – joudia Jul 03 '22 at 16:18