Резюме: Я хочу получить функцию, которая выводит точные типы, с которыми она была вызвана, и принимает (например) кортеж, который передает их (типы которых будут отличаться от точных типов, с которыми была вызвана функция).
Я застрял, пытаясь "узнать" с помощью дедукции типы аргументов данной функции, одновременно пересылая их. Мне кажется, что я упускаю что-то важное в том, как это работает.
#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);
}
Что я хотел бы видеть, так это сценарий, когда моя функция (например, g1
или g2
) вызывается, она знает и может использовать как исходные типы - int,double,void*,std::string&,const char*
так и пересылаемые аргументы.
В данном случае я не могу найти эту информацию в g1
или g2
. Ошибка компоновщика (намеренная, чтобы вывести типы) показывает, что в g1
они такие:
int&, double&, void*&, std::string&, char const*&
int&, double&, void*&, std::string&, char const*&
и в g2
:
int, double, void*, std::string, char const*
int&, double&, void*&, std::string&, char const*&
Здесь есть две вещи, которые я не понимаю:
Почему ни один из выведенных (через ошибку компоновщика) типов не соответствует тому, что я фактически передал? (int,double,void*,std::string&,const char
). Могу ли я вывести, что мне на самом деле передали? Желательно с "естественным" синтаксисом, т.е. все только один раз и ничего явно не выписано. Я могу явно написать:
g2(f,std::forward_as_tuple(i,d,ptr,sref,cstr),i,d,ptr,sref,cstr))
но это, мягко говоря, "громоздко"!
В g1
наличие &&
в объявлении сигнатуры функции, похоже, изменяет типы в самом параметре шаблона Args
. Сравните это с:
template
void test(T t);
Или:
template
void test(T& t);
используя любой из них с:
int i;
test(i);
не изменяет тип T
. Почему &&
изменяет тип самого T
, а &
- нет?