据我所知,模板无法从分配中推断出类型,即
template <typename T>
T aFunction (int a) { /*...*/ }; // This obviously won't work
这很明显为什么。但是这个将工作:
template <typename T>
T aFunction (T a, T b) { return a + b; }; // a-ok
'因为T
将从参数中推断出来。我想从中推断一下:
template <typename T>
T aFunction (std::function<T(int)> a) { return a(3);};
^
|
I specified it! ----------
因此,在使用时,函数应该做什么没有歧义:
std::function<double(int)> blah = [](int x){ return x / 2.0f; };
aFunction(blah);
唉,编译器不会与我合作:
没有匹配的成员函数来调用'aFunction'
忽略了候选模板:无法匹配 '功能'对''(lambda at file.hpp:274:16)'
有没有办法让这种情况发生?缺少模板专业化(这是一个非常泛型类),或者是一个虚拟参数(我还不是那么绝望)。
Pd积:
完全披露:上面只是问题的简化,正是我需要的是:
template <typename T>
class MyStuff {
template <typename ReturnType>
MyStuff<ReturnType> aFunction(std::function<ReturnType(T)> a){
/*for each stuff in MyStuff do a(stuff)*/
}
}
其中MyStuff
包含T
类型的属性和一堆inline
函数,例如aFunction
。
答案 0 :(得分:5)
如评论中所述,这有效:
#include <functional>
template <typename T>
struct MyStuff {
template <typename ReturnType>
MyStuff<ReturnType> aFunction(std::function<ReturnType(T)> a){
return {};
}
};
int main() {
MyStuff<int> stuff;
std::function<double(int)> fn = [](int) { return 0.; };
stuff.aFunction(fn);
}
相反,这不起作用:
int main() {
MyStuff<int> stuff;
stuff.aFunction([](int) { return 0.; });
}
错误是问题中的错误:
注意:候选模板被忽略:无法匹配'function'与'(lambda at main.cpp:15:21)'
原因是类型推导仅适用于确切类型。不允许转换。在你的情况下,编译器应首先推导出lambda的所有返回类型,而不是以某种方式将其转换为std::function
,最后从使用lambda构造的函数中推导出函数的返回类型。
这不是类型推导的工作方式。
您可以使用以下方法解决问题:
template <typename T>
struct MyStuff {
template <typename F>
auto aFunction(F &&f) -> MyStuff<decltype(std::forward<F>(f)(std::declval<T>()))> {
return {};
}
};
在Coliru上查看。