Opracowuję stosunkowo prosty program (właściwie kalkulator). Jednak zdecydowałem się uczynić wszystkie elementy mojego programu tak ogólne, jak to możliwe, ponieważ:Funkcje polimorficzne (ogólne) jako argumenty w C++
- To dobra praktyka.
- Zachowuje rzeczy interesujące.
W ramach tego programu używam klasy Tuple
, którą piszę. Wiem, że klasa już istnieje, ale lubię mieć pełną kontrolę nad moim kodem i to jest tylko ćwiczenie.
Jedna rzecz, którą muszę zrobić, to przekształcić krotkę wyrażeń (gdzie same wyrażenia są ogólne) w krotkę zawierającą wyniki ocen wyrażeń. Krótko mówiąc, mam (z części trywialne pominięta):
template <class T>
class Expression {
public:
virtual T Eval() = 0;
// ...
};
template <class First, class ... Rest>
class Tuple {
// ...
private:
First first;
Tuple<Rest ...> rest;
};
I chciałbym się specjalizować na krotki generycznego typu jak ten:
template <template <class> class R, class First, class ... Rest>
class Tuple<R<First>, R<Rest> ...> {
// and here is the problem:
Tuple<First, Rest ...> Transform(function<template<class T> T(R<T>)>);
};
Po co może zrobić to:
template <class T> // There has to be a better way to do this
T Eval(Expression<T>& expr){
return expr.Eval();
}
// ...
Tuple<First, Rest ...> tuple = exprs.Transform(Eval);
Istnieje kilka miejsc, gdzie tu nie jestem pewien, jak się do tego zabrać rzeczy i prawdziwego eksperta, który mógłby mi pomóc tutaj będą mile widziane. Spodziewam się, że ten kod nie skompiluje się z powodu drobnych wad, ale nie o to chodzi - Moim głównym zmartwieniem jest linia, którą zaznaczyłem. Jeśli dobrze pamiętam z tego krótkiego okresu, nauczyłem się Haskella, funkcja ta powinna być w Rank-2 (jeśli nie, proszę o komentarz, a ja usunę tag). To po prostu nie wygląda dobrze. Czy jest jakiś sposób to zrobić?
Aktualizacja:
poradzono mi, aby spróbować przekazać funktor z ogólnej operator()
jako szablon argumentu, ale to nie działa.
Spróbuj 'boost :: mpl :: transform'. –
@ n.m. - To nie zapewnia funkcjonalności, której szukam. – user2008934
@dyp - Tak, robię, To jest czysta wirtualna funkcja. Ale nie o to chodzi. Chodzi o to - jak przekazać funkcję ogólną jako argument? – user2008934