Summary. I want to get a function that outputs the exact types with which it was called, and accepts (for example) a tuple that forwards them (the types of which will differ from the exact types with which the function was called).
I was stuck trying to "find out" through deduction of the types of arguments of this function, while sending them. I think that maybe I am missing something important in how this works.
#include <tuple> #include <string> #include <functional> template <typename ...Args> struct unresolved_linker_to_print_the_type { unresolved_linker_to_print_the_type(); }; void f(int,double,void*,std::string&,const char*) { } template <typename F, typename ...Args> void g1(F func, Args&&... args) { unresolved_linker_to_print_the_type<Args...>(); auto tuple = std::forward_as_tuple(args...); unresolved_linker_to_print_the_type<decltype(tuple)>(); } template <typename F, typename T, typename ...Args> void g2(F func, const T& tuple, Args... args) { unresolved_linker_to_print_the_type<Args...>(); unresolved_linker_to_print_the_type<decltype(tuple)>(); } int main() { int i; double d; void *ptr; std::string str; std::string& sref = str; const char *cstr = "HI"; g1(f, i,d,ptr,sref,cstr); g2(f, std::forward_as_tuple(i,d,ptr,sref,cstr), i,d,ptr,sref,cstr); }
What I would like to see is a scenario where my function (for example, g1 or g2 ) is called, it knows and can use both the original types - int,double,void*,std::string&,const char* , so and redirected measures.
In this case, I seem to be unable to find this information from g1 or g2 . ((Intentional to print types) The linker error shows me in g1 that they are:
int&, double&, void*&, std::string&, char const*& int&, double&, void*&, std::string&, char const*&
and in g2 :
int, double, void*, std::string, char const* int&, double&, void*&, std::string&, char const*&
There are two things that I cannot get here:
Why does not one of those printed (through linker errors) match what I really transmitted? ( int,double,void*,std::string&,const char ). Can I understand what I actually got? Preferably with a "natural" syntax, i.e. All only once and nothing is clearly written out. I can explicitly write:
g2<decltype(&f),decltype(std::forward_as_tuple(i,d,ptr,sref,cstr)),int,double,void*,std::string&,const char*>(f,std::forward_as_tuple(i,d,ptr,sref,cstr),i,d,ptr,sref,cstr);
but it is "cumbersome", to say the least!
In g1 presence of && in the function signature declaration seems to change the types in the Args template parameter. Compare this to:
template <typename T> void test(T t);
Or:
template <typename T> void test(T& t);
using any of them with:
int i; test(i);
does not change type T Why does && change type T when & does not work?