我是一名 Scala/Java 程序员,希望重新接触 C++ 并学习 C++0x 中一些令人兴奋的功能。我想从设计我自己的基于 Scala 集合的稍微有点功能的集合库开始,这样我就可以对模板有一个扎实的理解。我遇到的问题是编译器似乎无法推断出模板函数对象的任何类型信息。
FC++似乎已经使用“签名”解决了这个问题。这些看起来与 result_type 类型名非常相似,我想我会使用新的函数语法来获得它。如果可能的话,谁能建议一种在 C++0x 中做这种事情的方法,或者至少解释一下 FC++ 是如何做到这一点的?这是我正在玩的一段代码
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
template<class T>
class ArrayBuffer {
private:
vector<T> array;
public:
ArrayBuffer();
ArrayBuffer(vector<T> a) : array(a) {}
template<typename Fn>
void foreach(Fn fn) {
for(unsigned int i = 0; i < array.size(); i++) fn(array[i]);
}
template<typename Fn>
auto map(Fn fn) -> ArrayBuffer<decltype(fn(T()))> {
vector<decltype(fn(T()))> result(array.size());
for(int unsigned i = 0; i < array.size(); i++) result[i] = fn(array[i]);
return result;
}
};
template<typename T>
class Print {
public:
void operator()(T elem) { cout<<elem<<endl; }
};
template<typename T>
class Square{
public:
auto operator()(T elem) -> T {
return elem * elem;
}
};
int main() {
vector<int> some_list = {5, 3, 1, 2, 4};
ArrayBuffer<int> iterable(some_list);
ArrayBuffer<int> squared = iterable.map(Square<int>()); // works as expected
iterable.foreach(Print<int>()); // Prints 25 9 1 4 16 as expected
iterable.foreach(Print()); // Is there a way or syntax for the compiler to infer that the template must be an int?
ArrayBuffer<int> squared2 = iterable.map(Square()); // Same as above - compiler should be able to infer the template.
}
最佳答案
您可以制作 operator()
也是一个模板
class Print {
public:
template<typename T>
void operator()(T elem) { cout<<elem<<endl; }
};
那你可以传Print()
.用于传递参数,如 ArrayBuffer<decltype(fn(T()))>
我建议使用 declval
,所以你也可以使用非默认构造 T
ArrayBuffer<decltype(fn(declval<T>()))>
关于C++0x 模板函数对象推断,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3809874/