Vengo da Haskell e attualmente sto lavorando con C++ 11 per vedere cosa può fare. Uno dei miei giocattoli è un piccolo modello che tenta di imitare la funzione Haskell map
, vale a dire accetta un contenitore di valori di X
e una funzione che associa uno X
a un Y
e produce un contenitore di valori di Y
. So che potrei facilmente farlo usando std::transform
, ma questo rovinerebbe il divertimento.Come posso lasciare che il compilatore deduca il tipo di ritorno di un modello?
In questo momento, il mio modello assomiglia a questo:
template <typename T, typename U>
void myMap(const T &input,
U &output,
std::function<typename U::value_type (typename T::value_type)> f);
Ora, la mia qustion è: è possibile regolare la firma in modo che invece di prendere il contenitore di uscita per riferimento (secondo argomento) io cedo un nuovo contenitore tramite il valore di ritorno e tuttavia il compilatore può dedurre il tipo di reso? Qualcosa di simile
template <typename T, typename U>
U myMap(const T &input,
std::function<typename U::value_type (typename T::value_type)> f);
purtroppo non può essere chiamato come
std::vector<int> x = { 1, 2, 3, 4 };
std::list<bool> y = myMap(x, [](int x) { return x % 2 == 0; });
... almeno Clang non riesce a dedurre il tipo di ritorno qui.
Un'idea che avevo era che dato che il tipo di contenitore di input e il tipo di funzione sono noti, è possibile costruire il tipo di output da quello. Cioè qualcosa come
template <typename C, typename T, typename U>
C<U> myMap(const C<T> &input,
std::function<U (T)> f);
... ma ahimè C<U>
non sembra nemmeno di essere sintassi valida. Mi chiedo se ho solo bisogno della giusta polvere fata decltype
come nel caso this question.
Mi ricordo di aver fatto qualcosa di simile a quello che volevi, eccetto che non funzionava molto bene con 'std :: string' perché era' std :: basic_string 'e il suo passaggio faceva sì che fossero cose come' std: : basic_string '. Comunque ho un tentativo che funziona su tutto il resto. –
Rapptz
È 'auto y = mappa (x, [] (int x) {...});' accettabile? Non è possibile dedurre il tipo restituito in C++. –
zch
In C++ normalmente non lavoriamo direttamente con i contenitori, ma lavoriamo con gli intervalli di iteratore. Haskell e C++ non si traducono bene l'uno con l'altro. Per ogni lingua, impara i suoi modi. –