我已经在Clojure(一种功能语言)编程了一段时间了,我不得不使用C++作为一个类。我一直在尝试使用我在Clojure中享受过的一些功能(例如,高阶函数,lambda表达式,参数线程,动态输入等),但我已经遇到了一些砖墙。具有模板的高阶函数?
首先,我已经实现的功能get
采用两个参数:
- 集合(向量,列表,哈希映射等),和
- 索引
并返回该索引处的元素。
我还实现的功能conj
采用两个参数:
- 集合(向量,列表,队列,等等),以及
- 元素/对象(无论何种类型的集合是)
并返回添加了元素的集合。在矢量的情况下,这与push_back
大致相同。
现在,我要为“前进”或“线程”的论据使用像这样的高阶函数能够:
using std::vector;
vector<double> my_vec;
forward(my_vec, // take "my_vec"
conj(0.1), // "push" the value of 0.1 to the back of "my_vec"
get(0), // retrieve the first value
inc); // increment that value
这是一样inc(get(conj(my_vec, 0.1), 0);
,但很多更具可读性(!) 。
在这种情况下,forward
的返回值应该是1.1。
为了使forward
函数正常工作,初始参数后面的参数都需要是高阶函数。也就是说,他们需要工作类似于以下内容:
template<typename Func>
Func get(int i){
return [i](vector<boost::any> coll)
-> boost::optional<boost::any> {
return get(coll, i);
};
}
然而,编译器不能推断出要返回的lambda函数的类型。另外,根据我对boost::any
的极其有限的经验,我的猜测是它不能将vector<double>
转换为vector<boost::any>
,尽管boost::any
的明显权利要求是它可以作为几乎任何类型的替代品。
我想get
函数是一般的,所以我不想使用boost::function<double (vector <double>, int)>
,或任何类似的特定类型。
此外,如果从get
请求的索引超出范围,我正在使用boost::optional
而不是vector
返回null_ptr
。
因为它的立场,这是我forward
功能的外观:
template <typename T1>
optional<T1> forward (T1 expr1){
return expr1;
}
template <typename T1, typename T2>
optional<T1> forward (T1 expr1, T2 expr2){
return forward(expr2(expr1));
}
template <typename T1, typename T2, typename T3>
optional<T1> forward (T1 expr1, T2 expr2, T3 expr3){
return forward(expr2(expr1), expr3);
}
等...
有关如何使forward
函数正常工作的任何想法?
我也敢肯定有实现它比做元数超载,因为我有一个更有效的方式。
查找一元函数和continuators,功能PROG猛击概念。 [看看它是如何在C++ 11中实现的。](http://stackoverflow.com/a/25342660/701092) – 0x499602D2 2014-08-29 15:33:49
什么是编译器和版本? – 2014-08-29 15:43:41