柯里函数的惰性类型推断
Lazy type-inference for curried functions
在以下示例中,对mkPair2
调用的类型推断失败:
#include <functional>
template <class A, class B>
struct Pair {
A left; B right;
};
template <class A, class B>
Pair<A,B> mkPair1 (A left, B right) {
return (Pair<A,B>) { left, right };
}
template <class A, class B>
std::function<Pair<A,B>(B)> mkPair2 (A left) {
return [left] (B right) {
return (Pair<A,B>) { left, right };
};
}
Pair<int, char> ex1 = mkPair1 (2, 'a');
Pair<int, char> ex2 = mkPair2 (2) ('a');
问题是mkPair2
有两个模板参数,但调用(2)
只为它提供了其中一个,所以编译器立即举手并决定程序是模棱两可的,即使第二种类型可以从下面的('a')
调用中推断出来。
这可以通过手动mkPair2<int,char> (2) ('a')
给编译器类型来解决,但是不得不像这样握住编译器的手很快就会变老。
有没有办法诱使编译器继续类型检查,前提是每个类型最终都会被解析?
即使第二种类型可以从以下 ('a'( 调用中推断出来。
是的,可以推断,但C++规则不允许这样做。 类型推断仅发生在函数参数上。 因此,如果您缺少模板参数的函数参数,则需要自己指定它。
也就是说,C++14 的自动返回类型推导和通用 lambda 将使您不必指定任何内容。 您可以将代码重写为
template <class A, class B>
struct Pair {
A left; B right;
};
template <class A, class B>
auto mkPair1 (A left, B right) {
return Pair<A,B>{ left, right };
}
template <class A>
auto mkPair2 (A left) {
return [left] (auto right) {
return Pair<A, decltype(right)>{ left, right };
};
}
Pair<int, char> ex1 = mkPair1 (2, 'a');
Pair<int, char> ex2 = mkPair2 (2) ('a');
一切都会为你推断出来。 它还返回 lambda 对象,而不是std::function
,因此您可以避免std::function
使用的类型擦除的成本。
除了 @NathanOliver 的答案之外,您还可以通过自己创建通用 lambda 的等效项来使其也适用于 C++11:
template <class A>
struct X {
A left;
X(A left) : left(left) {}
template <class B>
Pair<A,B> operator()(B right) {
return Pair<A,B>{left, right};
}
};
然后:
template <class A>
X<A> mkPair2(A left) {
return X<A>(left);
}
相关文章:
- 特征::矩阵<双精度,1,3> 结构类型函数中的返回类型函数
- 将C++子类成员函数(虚拟实现)传递给 C 类型函数指针
- C++ 这里有一个返回 (24) 的布尔返回类型函数
- 使用SFINAE来检测void返回类型函数的存在
- 使用此类型函数有什么优势
- 为什么此函数通过类型函数指针调用后,呼叫明智地行为
- 如何使用无类型函数指针调用C++成员函数
- 模板返回类型函数如何在C++中工作
- 具有通用类型函数的动态库[C ]
- 如何在返回类型函数模板的专用化中使用派生类型?( "couldn't infer template argument" )
- Bon appetit :从 int 返回类型函数在 main() 中打印字符串
- 对于需要其他模板参数的类型函数的部分模板专业化
- c++错误的参数类型-函数指针
- 延迟评估模板类型函数
- 在引用或指针返回类型函数上输入
- 具有指针数据类型的非类型函数模板参数
- STL中使用的C++自定义比较类型(函数谓词与较少结构)
- C++模板基类的非类型函数模板的 using 声明
- 字符串到类型函数,模板专用化使调用统一
- 自由类型函数可以接受 Unicode 文件名吗?