2016-08-25 16 views
4

Ich habe das schon auf der Boost-Mailingliste gefragt, aber ich war mir nicht so sicher, was meine Absichten waren. Es könnte mir auch nicht ganz klar sein, wie ich das erreichen kann.Mehrere Karten zusammenfügen

ich mehrere Karten in hana finden Sie im folgenden Codebeispiel zusammenführen möchten:

constexpr auto m1 = hana::make_map(
    hana::make_pair("key1"_s, hana::type_c<std::string>), 
    hana::make_pair("key2"_s, hana::type_c<std::string>) 
); 

constexpr auto m2 = hana::make_map(
    hana::make_pair("key3"_s, hana::type_c<std::string>), 
    hana::make_pair("key4"_s, hana::type_c<std::string>), 
    hana::make_pair("key5"_s, hana::type_c<std::string>) 
); 

constexpr auto m3 = hana::make_map(
    hana::make_pair("key6"_s, hana::type_c<std::string>), 
    hana::make_pair("key7"_s, hana::type_c<std::string>), 
    hana::make_pair("key8"_s, hana::type_c<std::string>) 
); 

Ich habe bereits eine Antwort, wie dies zu tun für zwei Karten:

constexpr auto result = hana::fold_left(m1, m2, hana::insert); 
constexpr auto expected = hana::make_map(
    hana::make_pair("key1"_s, hana::type_c<std::string>), 
    hana::make_pair("key2"_s, hana::type_c<std::string>), 
    hana::make_pair("key3"_s, hana::type_c<std::string>), 
    hana::make_pair("key4"_s, hana::type_c<std::string>), 
    hana::make_pair("key5"_s, hana::type_c<std::string>) 
); 

Als ich das geprüft Dokumentation kann ich sehen, dass fold_left 2 oder 3 Argumente benötigt.

Es sieht aus wie ich brauche so etwas wie: fold_left (fold_left (m1, m3, hana :: einfügen), m2, hana :: einfügen);

template<typename Map...> 
constexpr auto merge_multiple_maps(Map... args) { 
    // do something useful here... 
} 

Aber ich bin nicht sicher, wie hier verfahren und ich habe noch nicht so viel Erfahrung in der Meta-Programmierung ...

Grüße, Matthijs

Antwort

3

Zuerst merge2 wie folgt definieren :

auto merge2 = [](auto&& m1, auto&& m2) { 
    return hana::fold_left(std::forward<decltype(m1)>(m1), 
         std::forward<decltype(m2)>(m2), 
         hana::insert); 
}; 

Dann definieren merge als die rekursive Anwendung der merge2:

auto merge = [](auto&& m1, auto&& ...ms) { 
    return hana::fold_left(
    hana::make_basic_tuple(std::forward<decltype(ms)>(ms)...), 
    std::forward<decltype(m1)>(m1), 
    merge2 
); 
}; 

Ich habe diese Implementierung nicht getestet, aber es sollte Ihnen die Idee geben. Wenn Ihnen die perfekte Weiterleitung nicht wichtig ist, können Sie alle static_cast; Dies ist nur für die Laufzeit-Effizienz, für den Fall, dass Sie Arten speichern, die in Ihrer Karte teuer zu kopieren aber billig sind. Außerdem können Sie dies nicht in einem constexpr Kontext verwenden, da Lambdas nicht in konstanten Ausdrücken angezeigt werden können. Dies wird in C++ 17 behoben, aber im Moment können Sie Funktionsobjekte, die diesen Lambdas entsprechen, relativ einfach implementieren.

[Edit:. Hana in der Zukunft irgendwann diese merge Funktion implementieren kann] [Edit:. Verwenden std::forward statt static_cast]

+0

Sollte nicht 'std vorwärts :: (m1) 'Arbeit, zur Selbstdokumentation? – Quentin

+0

Ja, tut mir leid. Ich habe die Angewohnheit, 'static_cast' in Hana's Implementierung zu verwenden, weil es 1 weniger Funktionsinstanziierung verursacht (und das macht einen Unterschied in Hana), aber ich werde meine Antwort bearbeiten, weil' std :: forward' klarer ist. –

Verwandte Themen