2016-05-23 13 views
5

bir boost::hana::map içinde (bir anahtar ve yeni bir değer verilir) değerini güncellenmesi kanonik yolu nedir? Kanonik yön/`boost :: hana :: map` bir harita değerinin değiştirilmesi

Ben boost::hana::replace_if kullanarak çalıştı ama bir Functor değil gibi map çalışmıyor - Ben bir map geri ardından tuple için map dönüştürerek ve işe almak, ancak verimsiz geliyor.

Şu anda kullanıyorum alternatif map::erase_key ve ardından map::insert çağırıyor.

Bu amaçla eksik olduğum için tasarlanmış herhangi bir replace veya update işlevi var mı? Yoksa bu bir değeri güncellemenin "kanonik" hali mi?

cevap

4

Bunu yapmanın kanonik bir yolu olduğunu sanmıyorum. Bunun için geçerli kullanım durumları mevcutsa, belki de bunu desteklemek için orada bir işlev bulabiliriz. hana::erase_key ile ilgili sorun, yeni bir harita oluşturacak ve hana::insert ile tekrar olacaktır. Şu an için, hana::unpack kullanarak ve daha sonra yeni bir harita oluşturmak muhtemelen en iyi bahistir.

başka not
#include <boost/hana.hpp> 

namespace hana = boost::hana; 

template <typename NewPair> 
struct replace_helper_t 
{ 
    NewPair const& new_pair; 

    template <typename Pair> 
    constexpr decltype(auto) operator()(Pair&& p) const 
    { 
    return hana::if_(
     hana::equal(hana::first(new_pair), hana::first(p)), 
     new_pair, 
     std::forward<Pair>(p) 
    ); 
    } 
}; 

struct replace_t 
{ 
    template <typename Map, typename NewPair> 
    constexpr auto operator()(Map&& m, NewPair&& new_pair) const 
    { 
    return hana::unpack(std::forward<Map>(m), 
     hana::on(
     hana::make_map, 
     replace_helper_t<NewPair>{std::forward<NewPair>(new_pair)} 
    ) 
    ); 
    } 
}; 

constexpr replace_t replace{}; 

int main() 
{ 
    auto my_map = hana::make_map(
    hana::make_pair(hana::int_c<7>, 7), 
    hana::make_pair(hana::int_c<13>, 13), 
    hana::make_pair(hana::int_c<23>, 23) 
); 

    auto new_map = replace(my_map, hana::make_pair(hana::int_c<13>, 14.0f)); 

    BOOST_HANA_RUNTIME_ASSERT(new_map == 
    hana::make_map(
     hana::make_pair(hana::int_c<7>, 7), 
     hana::make_pair(hana::int_c<13>, 14.0f), 
     hana::make_pair(hana::int_c<23>, 23) 
    ) 
); 
} 

, belki hana::map bir Functor olmalıdır.

+2

Hana :: hash (hana :: first (new_pair)) == hana :: hash (hana :: first (p)) 'olması gereken hana :: equal (hana :: ilk (new_pair), hana :: ilk (p)) '. Aksi halde, hash eşlemi haritada başka bir anahtarla çarpışan bir anahtarla ilişkilendirilmiş olan değeri değiştirirseniz, anahtarlar farklı olsa bile aynı karma değeri paylaşan tüm anahtarların değerini değiştirirsiniz. Temel olarak aynı gruptaki tüm tuşların değerini değiştirirsiniz. Ve bir nitpick, ancak 'hana :: equal' kullanıldığında, jenerik kod için '==' daha iyi olabilir, çünkü e. 'Std :: integral_constant'. –

+1

Ah, doğru. Örneğimi düzelttim ve değerin basitçe değişmediğini göstermek için değerin türünü değiştirdim. –

2

Değerin türünü değiştirmeniz gerekiyor mu? Değilse ve değeriniz atandığında, veya eşdeğerli hana::at_key(map, key) = new_value'u kullanabilirsiniz, hana::at_key bir başvuru döndürür.

Değiştirilecek değerin türüne ihtiyacınız varsa, bu daha da zor olur. Yerinde herhangi bir şey yapamayacağız çünkü değeri değiştirdikten sonra haritanın türü, değeri değiştirmeden önce türünden farklı olacaktır. Bu nedenle, yeni bir harita veya bu haritanın bir çeşit değiştirilmiş görünümü oluşturmalıyız (ancak şu anda görünümler desteklenmemektedir). erase_key ve insert kullanımı gerçekten iki haritanın oluşturulmasına neden olur, bu da verimsiz olur. Bunun yerine, aynısını sağlayacak bir çeşit update işlevini sağlayabilirdik, ancak haritanın yalnızca bir kopyasını oluşturabilirdik (sonuç). Kendi fonksiyonumuzu sağlayarak derleme süreleri açısından erase_key + insert'dan daha iyisini yapabileceğimize inanıyorum. İsteğinizi takip etmek için this issue'u açtım, çünkü böyle bir şey sağlamanın önemli olduğunu düşünüyorum; Teşekkürler.

Son olarak, Jason söylediklerini yorum yapmak istediğiniz: Başka bir kayda göre

, belki hana :: haritası olması gereken bir Funktör.

hana::map

bir funktor yapılmış olabilir, ama yine de Funktör yasalarına uygun transform haritanın tuşlara dokunduğunuzda olabilir emin değilim. Durum böyle değilse, "anahtarın bir miktar yüklemeyi karşılaması durumunda değeri XXX ile değiştirin" diyemezsiniz. hana::replace_if. hana::transform temel olarak temel anahtar/değer çiftleri dizisini temelde dönüştürdüyse kanunları yıkacak işlevlerin bir örneğini bulmak için denedim (ancak şu ana kadar başarısız oldum), ancak sezgim böyle bir örnek bulmak mümkün. # 278 sayısında devam edecek.

İlgili konular