Jestem programistą Scala/Java, który chce ponownie wprowadzić się do C++ i nauczyć się niektórych ekscytujących funkcji w C++ 0x. Chciałem zacząć od zaprojektowania mojej własnej, nieco funkcjonalnej biblioteki kolekcji, opartej na kolekcjach Scali, dzięki czemu mogłem uzyskać solidne zrozumienie szablonów. Problem, na który napotykam, polega na tym, że kompilator nie jest w stanie wywnioskować żadnych informacji o typach dla szablonowych obiektów funkcyjnych.C++ 0x obiektowe wnioskowanie obiektowe obiektu
FC++ wydaje się, że rozwiązało to za pomocą "Podpisy". Te wydają się bardzo podobne do typ_typu result_type i pomyślałem, że dostanę to używając nowej składni funkcji. Czy ktokolwiek może zaproponować sposób zrobienia tego w C++ 0x, jeśli to możliwe, lub przynajmniej wyjaśnić, w jaki sposób FC++ był w stanie to zrobić? Oto fragment kodu Grałem około z
#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.
}
Dziękujemy! To działa idealnie. Nie pomyślałem o przeniesieniu szablonu do operatora. Doceniam również wskazówkę dotyczącą deklwalacji. Mam krótką obserwację - czy istnieje sposób, aby to zrobić za pomocą wskaźnika funkcji na szablonie? Na przykład, jeśli mamy funkcję drukowania szablonu, mogę nazwać iterable.foreach (& print); Uważam, że odpowiedź brzmi nie. –