c++ 11使用std::函数进行类型演绎
C++11 Type Deduction With std::function
即使在阅读了许多在线资源和其他问题之后,包括从std::函数返回类型使用lambda和参数类型自动扣除和匿名lambda函数的模板参数类型扣除,我仍然难以在c++中清楚地表达以下内容。我希望避免重复的模板参数,这似乎是不必要的。
例如,泛型"A"的容器"H"有泛型"B"的泛型方法"M"。这表达了我对'H'和'M'方法的意图:
template<typename A>
struct H
{
explicit H(A x) : x(x) { }
A x;
template<typename B>
H<B> M(std::function<H<B>(A)> g) { return g(x); }
};
我的问题是调用'M'需要函数调用和返回容器的重复模板参数。对于'float'类型,这还不算太糟,但对于其他符号,这很快就变得难以管理了。
// This works but requires the duplicate 'float'
H<int>(1).M<float>([](int x) { return H<float>(x + 3.14); });
// These would be preferred, but neither works
H<int>(1).M<float>([](int x) { return H(x + 3.14); });
H<int>(1).M([](int x) { return H<float>(x + 3.14); });
从这个问题开始,我尝试用泛型函子类型'F'代替泛型结果类型'H'的新定义:
template<typename A>
struct H2
{
enum { IS_H2 = true };
explicit H2(A x) : x(x) { }
A x;
template<typename F,
class = typename std::enable_if<std::result_of<F(A)>::type::IS_H2>::type>
auto M(F g) -> decltype(g(x)) { return g(x); }
};
允许所需语法:
// This now is valid
H2<int>(1).M([](int x) { return H2<float>(x + 3.14); });
// And, as expected, this is not
H2<int>(1).M([](int x) { return x + 3.14; });
但我觉得"H2"几乎是无礼的,必须有更好的方法。
如何更清晰地限制函数的泛型返回类型,或者如何使std::函数与类型推断一起工作?还是我完全从错误的角度切入了问题?
函数模板就是这样工作的,没有别的办法。
如果函数形参中有一个形参,则自动进行模板形参推导,这里不是这种情况。例如,编译器可以在以下函数中推断类型:
template<typename B>
H<B> M(std::function<H<B>(A)> g, const B&) { return g(x); }
但是你必须传递一些虚拟值,这(我认为)不是你想要的。
下面是示例,由于模板形参推导失败,无法将lambda转换为std::function:
#include <functional>
template<typename A>
struct H
{
explicit H(A x) : x(x) { }
A x;
template<typename B>
H<B> M(std::function<H<B>(A)> g, const B&) { return g(x); }
};
int main()
{
H<int> h(1);
std::function<H<float>(int)> g( [](int x){ return H<float>(x + 3.14); } );
const auto v = h.M( g, 5.5f );
(void)v;
}
相关文章:
- 类型演绎 C++ 标准和自动
- λ类型演绎失败
- decltype(auto) 类型演绎:返回 x 与返回 (x)
- 使用decltype的动态多态类型演绎
- 普遍类型演绎scott-meyers
- c++ 11使用std::函数进行类型演绎
- 使用通用引用时进行类型演绎
- c++如何在无法进行类型演绎时调用模板化构造函数
- c#泛型中的类型演绎类似于c++模板
- 类型演绎不适用于std::function
- 为什么decltype返回类型在递归模板中失败,而返回类型演绎却工作得很好?
- 表达式模板中的按引用捕获可以与类型演绎共存
- 类型演绎模板函数c++
- 模板,类型演绎不足
- 括号初始化列表和函数模板类型演绎顺序
- 类型演绎的重载赋值操作符
- 静态方法中派生类的类型演绎
- 在类型演绎之后,函数模板中的替换顺序是否有任何保证
- 返回类型演绎是否可能
- c++ 14中赋值时的返回类型演绎