STL Namen für die „Karte“ funktionale Programmierung Funktion
-
01-10-2019 - |
Frage
Ich möchte etwas schreiben können, wie
char f(char);
vector<char> bar;
vector<char> foo = map(f, bar);
Die transform
Funktion erscheint ähnlich zu sein, aber es wird die Größe der resultierenden Sammlung nicht automatisch generieren.
Lösung
Sie können std::back_inserter
in <iterator>
verwenden, obwohl vor der Größe Bereitstellung effizienter ist. Zum Beispiel:
string str = "hello world!", result;
transform(str.begin(), str.end(), back_inserter(result), ::toupper);
// result == "HELLO WORLD!"
Andere Tipps
Diese Frage gestellt wurde, bevor die C ++ 11-Standard in Kraft getreten ist ... heute haben wir std::transform()
als (hässlich) äquivalent eine funktionale Programmierung ‚Landkarte‘. Hier ist, wie es zu benutzen:
auto f(char) -> char; // or if you like: char f(char)
vector<char> bar;
vector<char> foo;
// ... initialize bar somehow ...
std::transform(bar.begin(), bar.end(), std::back_inserter(foo), f);
Um diese Arbeit zu machen, müssen Sie die folgenden Beobachtungen:
- Um die Zuordnung effizienter zu gestalten, sollte die
map
Funktion nicht die Arbeit machen. Stattdessen sollten sie ihre Argumente in einem temporären Objekt speichern (in Ihrem Fall, das wäre eine Instanz vonclass map::result<char(*)(char), vector<char> >
sein) - Diese
map::result
temporären sollte einetemplate <typename T> operator T
Umwandlung hat. - Wenn die
map::result
zu einemstd::vector<char>
zugeordnet ist, ist diese Umwandlung der einzig gangbare. - Bei der Umwandlung Operator
class map::result<char(*)(char), vector<char> >::operator vector<char>
Sie die Eingabe und Rückgabetyp haben, und die Abbildungsfunktion. An dieser Stelle können Sie die Eingaben wirksam umwandeln können.
<edit>
Code
template<typename CONT, typename FUNC>
class mapresult {
CONT const& in;
FUNC f;
public:
template<typename RESULT> RESULT to() const
{
RESULT out;
for (auto const& e : in) { out.push_back(f(e)); }
return out;
}
template<typename RESULT> operator RESULT() const
{
return this->to<RESULT>();
}
mapresult(CONT const& in, FUNC f) : in(in), f(std::move(f)) { }
};
template<typename CONT, typename FUNC>
auto map(CONT const& in, FUNC f) -> mapresult<CONT, FUNC>
{
return mapresult<CONT, FUNC>(in, f);
}
Verwenden Sie wie folgt aus:
using namespace std;
char foo(char c) { return c | ('A' ^ 'a'); }
std::string in = "Test";
int main(int argc, char* argv[])
{
string out = map(in, &foo);
cout << out << endl;
char replace = 'e';
cout << map(in, [replace](char c){return c == replace ? '?' : c; }).to<string>();
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow