C++ 以函数为参数提取模板函数中输入参数的类型
我有这个功能:C++ 以函数为参数提取模板函数中输入参数的类型,c++,function,templates,signature,C++,Function,Templates,Signature,我有这个功能: template<typename T, int (*F)(T&)> void DoStuff(T& s) { auto an = make_any<T>(s); cout << _GetDataFromAny<MyStruct, F>(an); } 模板 空隙度凝灰岩(T&s) { auto an=使任何(s); cout您可以编写一个助手来推断返回int的函数指针的参数类型: template&
template<typename T, int (*F)(T&)>
void DoStuff(T& s)
{
auto an = make_any<T>(s);
cout << _GetDataFromAny<MyStruct, F>(an);
}
模板
空隙度凝灰岩(T&s)
{
auto an=使任何(s);
cout您可以编写一个助手来推断返回int
的函数指针的参数类型:
template<typename T>
T arg_type(int(*)(T&));
模板
T arg_类型(int(*)(T&));
然后稍微重写函数模板,将函数指针作为非类型模板参数,并从中找出参数类型
template<auto F, typename T = decltype(arg_type(F))>
void DoStuff(T& s) {
// ...
}
模板
空隙度凝灰岩(T&s){
// ...
}
免责声明:这个答案经过了一系列的编辑和更正,非常感谢Jarod42的耐心和帮助,感谢cigien的富有成效的讨论。它比必要的时间长了一点,但我觉得值得保留一点历史。它是:最简单的/我更喜欢的一个/对以前的混乱的一些解释要快速回答,请阅读第二部分
简单的
您可以使用auto
模板参数(自C++17以来)作为函数指针,并从参数中推断T
:
template<auto F, typename T>
void DoStuff(T& s)
{
int x = F(s);
}
int foo(double&){ return 42;}
int main() {
double x;
DoStuff<&foo>(x);
}
现在,以前只会发生在模板(1)内部的错误已经发生在main
(2)中,并且错误消息更清晰
“错误”
主要是好奇心,考虑从函数指针推导参数类型的方法:
template <typename T> struct param_type;
template <typename R,typename P>
struct param_type< R(*)(P&)> {
using type = P;
};
template<auto F, typename T = typename param_type<decltype(F)>::type>
void DoStuffX(T& s)
{
}
int foo(double&){ return 42;}
int main() {
double x;
DoStuffX<foo>(x);
}
原因是当可以从传递的参数中删除T
时,不使用默认模板参数(请参阅)。即,DoStuffX(x);
实际实例化DoStuffX
。我们仍然可以通过以下方式获得默认模板参数:
int main() {
std::string x;
auto f_ptr = &DoStuffX<foo>;
f_ptr(x); // error
}
intmain(){
std::字符串x;
自动f_ptr=&DoStuffX;
f_ptr(x);//错误
}
现在用std::string
调用DoStuffX
是一个编译器错误,因为这里DoStuffX
被实例化为DoStuffX
,使用默认参数(当DoStuffX
被实例化时,没有参数可用于推断T
).我养成了只在写完后重新加载的习惯,更容易看出另一个答案比我的好,而不是试图竞争:嗯,这太快了!我还不能接受答案(所以不让我接受)@magnize_prime_是_463035818是的,我知道你的意思。但是,它并没有真正的竞争;你的解决方案同样有效,发布它也可以。当然,竞争不是,我是在开玩笑。我只是不知道我的会添加什么。我可以尝试在不使用auto
参数的情况下获取它,但现在已经很晚了请注意=decltype(arg_type(F))
很少有用,因为T
是推导出来的。(对auto-func=&DoStuff;
有用)模板void-DoStuffY(typename-param_-type::type&s)
是一种替代方法。完全没有推导。函数指针或常规调用是可能的(仅对预期类型)@Jarod42这应该是答案。一定是关于这个问题,不知怎的,我忘记了我知道的一切和更多。我会编辑的
int main() {
std::string x;
DoStuffX<foo>(x);
}
int main() {
std::string x;
auto f_ptr = &DoStuffX<foo>;
f_ptr(x); // error
}