Mein Problem mit std::transform
ist, dass ich nicht beide den Anfang und das Ende eines temporären Objekts erhalten kann.Python-ähnliche Karte in C++
Ich möchte eine Python-ähnliche Mapping-Funktion in C++ implementieren, die auf Vektoren eines Typs arbeitet und sie auf einen anderen Vektor (möglicherweise eines anderen Typs) abbildet.
Das ist mein Ansatz:
template <class T, class U, class UnaryOperator>
std::vector<T> map(const std::vector<T>& vectorToMap, UnaryOperator operation)
{
std::vector<U> result;
result.reserve(vectorToMap.size());
std::transform(vectorToMap.begin(), vectorToMap.end(),
std::back_inserter(result), [&operation] (U item) { return operation(item); });
return result;
}
Und dies ist ein Beispiel dafür, wie ich beabsichtige, diese zu verwenden (wobei der Rückgabetyp des Filters die Art ihres ersten Arguments ist):
std::vector<std::shared_ptr<Cluster>> getClustersWithLength(const std::vector<Cluster>& clusterCollection, const int& length)
{
return map(filter(clusterCollection, [&length] (Cluster& cluster) {
return cluster.sizeY == length;
}),
[] (const Cluster& cluster) {
return std::make_shared<Cluster>(cluster);
});
}
Die Fehlermeldung, die ich für diesen Code zu bekommen ist jedoch:
error: no matching function for call to 'map(std::vector<Cluster>,
ClusterPairFunctions::getClustersWithLength(const
std::vector<Cluster>&, const int&)::<lambda(const Cluster&)>)'
note: candidate: template<class T, class U, class UnaryOperator> std::vector<_RealType> map(const std::vector<_RealType>&, UnaryOperator)
std::vector<T> map(const std::vector<T>& vectorToMap, UnaryOperator operation)
note: couldn't deduce template parameter 'U'
können Sie mir etwas Hilfe geben, wie kann ich es beheben? Kann ich irgendwie die statische Assertion zur Kompilierungszeit verwenden, um zu überprüfen, ob der Operationstyp (T t) U ist?
Entfernen U
und ersetzt die Erklärung des Ergebnisses mit std::vector<typename std::result_of<UnaryFunction(T)>::type> result;
noch erzeugt einen Fehler:
src/ClusterPairFunctions.cc: In function 'std::vector<std::shared_ptr<Cluster> > ClusterPairFunctions::getClustersWithLength(const std::vector<Cluster>&, const int&)':
src/ClusterPairFunctions.cc:130:14: error: could not convert 'map(const std::vector<_RealType>&, UnaryFunction) [with T = Cluster; UnaryFunction = ClusterPairFunctions::getClustersWithLength(const std::vector<Cluster>&, const int&)::<lambda(const Cluster&)>]((<lambda closure object>ClusterPairFunctions::getClustersWithLength(const std::vector<Cluster>&, const int&)::<lambda(const Cluster&)>{}, ClusterPairFunctions::getClustersWithLength(const std::vector<Cluster>&, const int&)::<lambda(const Cluster&)>()))' from 'std::vector<Cluster>' to 'std::vector<std::shared_ptr<Cluster> >'
return (map(filter(clusterCollection, [&length] (Cluster& cluster) {
In file included from src/../interface/ClusterPairFunctions.h:5:0,
from src/ClusterPairFunctions.cc:1:
src/../interface/../../../interface/HelperFunctionsCommon.h: In instantiation of 'std::vector<_RealType> filter(const std::vector<_RealType>&, UnaryPredicate) [with T = Cluster; UnaryPredicate = ClusterPairFunctions::getClustersWithLength(const std::vector<Cluster>&, const int&)::<lambda(Cluster&)>]':
src/ClusterPairFunctions.cc:132:4: required from here
src/../interface/../../../interface/HelperFunctionsCommon.h:52:15: error: no match for call to '(ClusterPairFunctions::getClustersWithLength(const std::vector<Cluster>&, const int&)::<lambda(Cluster&)>) (const Cluster&)'
if(predicate(*it)) result.push_back(*it);
^
src/ClusterPairFunctions.cc:130:68: note: candidate: ClusterPairFunctions::getClustersWithLength(const std::vector<Cluster>&, const int&)::<lambda(Cluster&)> <near match>
return (map(filter(clusterCollection, [&length] (Cluster& cluster) {
^
src/ClusterPairFunctions.cc:130:68: note: conversion of argument 1 would be ill-formed:
In file included from src/../interface/ClusterPairFunctions.h:5:0,
from src/ClusterPairFunctions.cc:1:
src/../interface/../../../interface/HelperFunctionsCommon.h:52:15: error: binding 'const Cluster' to reference of type 'Cluster&' discards qualifiers
if(predicate(*it)) result.push_back(*it);
^
src/../interface/../../../interface/HelperFunctionsCommon.h: In instantiation of 'std::vector<_RealType> map(const std::vector<_RealType>&, UnaryFunction) [with T = Cluster; UnaryFunction = ClusterPairFunctions::getClustersWithLength(const std::vector<Cluster>&, const int&)::<lambda(const Cluster&)>]':
src/ClusterPairFunctions.cc:135:4: required from here
src/../interface/../../../interface/HelperFunctionsCommon.h:64:9: error: could not convert 'result' from 'std::vector<std::shared_ptr<Cluster> >' to 'std::vector<Cluster>'
return result;
Dieser Code ist in C++ 11 nicht gültig. –
@AdamHunyadi Verbose C++ 11 Version hinzugefügt. – Yakk
@AdamHunyadi Tippfehler und restliche C++ 14 Sachen entfernt, Live-Beispiel enthalten. – Yakk