要約:最終的に、呼び出された正確な型を推測し、それらを転送するタプルを取得する関数を作成したいと思います(その型は、関数が呼び出された正確な型とは異なります)。
与えられた関数への引数のタイプを推測することで「知る」ことを試みながら、同時にそれらを転送しようとして立ち往生しています。私はこれがどのように機能するかについて重要な何かを見逃しているかもしれないと思います。
#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);
}
私が見たいのは、私の関数(egg1
またはg2
)が呼び出されたときに、元のタイプint,double,void*,std::string&,const char*
と転送されたarugmentsの両方を認識して使用できるシナリオです。
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*&
ここで得られないことが2つあります。
印刷された(リンカーエラーを介した)タイプのいずれも、実際に渡したものと一致しないのはなぜですか?(
int,double,void*,std::string&,const char
)。私が実際に渡されたものを推測できますか?できれば「自然な」構文を使用します。つまり、すべてを1回だけ、明示的に何も書き出さないようにします。私は明示的に書くことができます: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);
しかし、それは控えめに言っても「扱いにくい」です!
関数に
g1
存在&&
する場合、署名宣言はテンプレートパラメータArgs
自体の型を変更するようです。それを以下と比較してください:template <typename T> void test(T t);
または:
template <typename T> void test(T& t);
次のいずれかを使用します。
int i; test(i);
のタイプは変更されません
T
。変更しないのに、なぜそれ自体&&
のタイプを変更するのですか?T
&