Eine rekursive_Transform für std :: array mit verschiedenen Rückgabetypen
Dies ist eine Folgefrage für A recursive_transform für std :: vector mit verschiedenen Rückgabetypen . Dank G. Sliepen geben Sie weitere Überprüfungsvorschläge. Nachdem recursive_transformich mich mit dem Thema befasst habe, eine allgemeinere Funktion sowohl für verschiedene Ausgabetypen als auch für verschiedene Containertypen zu erreichen, habe ich immer noch keine einfache Lösung. Allerdings basiert auf G. SLIEPEN Antwort , bei der std::vector, std::dequeund std::listContainertypen gelöst werden kann. Ich versuche zusätzlich eine weitere Überlastfunktion recursive_transformfür zu implementieren std::array. Hier ist meine Implementierung.
template<class T, std::size_t S, class F>
auto recursive_transform(std::array<T, S>& input, const F& f)
{
using TransformedValueType = decltype(recursive_transform(*input.cbegin(), f));
std::array<TransformedValueType, S> output;
std::transform(input.cbegin(), input.cend(), output.begin(),
[f](auto& element)
{
return recursive_transform(element, f);
}
);
return output;
}
Der Testfall von std::array:
// std::array<int, 10> -> std::array<std::string, 10>
std::array<int, 10> test_array;
for (int i = 0; i < 10; i++)
{
test_array[i] = 1;
}
auto recursive_transform_result5 = recursive_transform(
test_array,
[](int x)->std::string { return std::to_string(x); }); // For testing
std::cout << "string: " + recursive_transform_result5.at(0) << std::endl;
Hier ist der Godbolt-Link . Der Code in diesem Link einschließlich der Testfälle für std::vector, std::dequeund std::list.
Alle Vorschläge sind willkommen.
Die zusammenfassenden Informationen:
Welcher Frage folgt es?
Eine rekursive Transformation für std :: vector mit verschiedenen Rückgabetypen
Welche Änderungen wurden seit der letzten Frage am Code vorgenommen?
Der handhabbare Containertyp in der vorherigen
recursive_transformFunktionsversion iststd:vector. Mit G. SLIEPEN Antwort , diese handhabbar Containertyp - Liste wird erweitertstd::vector,std::dequeundstd::list. Dann versuche ichstd::arrayhier umzugehen .Warum wird nach einer neuen Bewertung gefragt?
In dieser
recursive_transformFunktionsversion scheint es, dass es im genannten Testfall gut funktioniertstd::array<int, 10> -> std::array<std::string, 10>. Es gibt jedoch einige Probleme, wenn es um den komplexeren Fall geht, wiestd::array<std::array<int, 10>, 10> -> std::array<std::array<std::string, 10>, 10>(die Skalierbarkeit muss verbessert werden!). Wenn es einen Vorschlag oder eine mögliche Idee dazu gibt, lassen Sie es mich bitte wissen.
Antworten
Stellen Sie sicher, dass Sie als constReferenz konsistent übergeben
Das Hauptproblem mit Ihrem Code war, dass Sie die std::arrayÜberladung nicht dazu gebracht haben , die Eingabe als constReferenz zu verwenden:
auto recursive_transform(std::array<T, S>& input, const F& f)
Einfach hinzufügen const! Sehen Sie diesen Godbolt-Link mit der std::arrayArbeit der verschachtelten s.
Verwenden Sie lieber std::begin()undstd::end()
Es spielt keine Rolle, ob Sie nur Container aus der Standardbibliothek unterstützen möchten, aber beim Schreiben von Vorlagen bevorzugen Sie die Verwendung von std::begin()und std::end()anstelle von ->begin()und ->end(). Der Vorteil besteht darin , dass , wenn Sie einen Nicht-Standard - Container irgendwo verwenden , das nicht bieten begin()und end()Funktionen Mitglied, wird es noch möglich sein , die out-of-Klasse zu überlasten std::begin()und std::end()Funktionen Iterator Unterstützung dieser Klasse hinzuzufügen. Wenn Sie es in Ihren Algorithmusvorlagen verwenden, unterstützen Ihre Algorithmen auch diese nicht standardmäßigen Klassen.