Re[4]: Метапрограммисты надоели
От: Evgeny.Panasyuk Россия  
Дата: 06.10.14 10:32
Оценка: 7 (1)
Здравствуйте, alex_public, Вы писали:

_>Да, это как мне кажется самый большой недостаток языка (ну про сложность мы упоминать не будем) в данный момент. Но в данном случае boost.fusion — это всё же на мой взгляд уж слишком костыльное решение.


Недостаток языка — это отсутствие compile-time reflection, Boost.Fusion для этого предлагает макросы BOOST_FUSION_DEFINE_STRUCT и подобные.
А вот те методы работы, которые предлагает Boost.Fusion с уже адаптированными структурами (то есть для которые есть необходимые гетерогенные итераторы) — вполне себе, ничего костыльного.

Даже как-то сравнивали в этом отношении Boost.Fusion vs Nemerle vs D (Fusion
Автор: Evgeny.Panasyuk
Дата: 24.10.13
, Nemerle
Автор: VladD2
Дата: 24.10.13
, D
Автор: D. Mon
Дата: 24.10.13
, all
Автор: Evgeny.Panasyuk
Дата: 25.10.13
) получилось вот так (даже без использования полиморфных лямбд):
struct Hasher
{
    template<typename T>
    size_t operator()(size_t hash, T x)
    {
        boost::hash_combine(hash, x);
        return hash;
    }
};

template<typename Struct>
size_t hash_it(const Struct &x)
{
    return boost::fusion::fold(x, size_t(0), Hasher{});
}
versus
[MacroUsage(MacroPhase.WithTypedMembers, MacroTargets.Class)]
macro ImplementGetHeshCode(typeBuilder : TypeBuilder)
{
  def fields = typeBuilder.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
  def make(field)
  {
    if (field.GetMemType().Equals(<[ ttype: int ]>))
      <[ result ^= this.$(field.Name : usesite) ]>
    else
      <[ result ^= this.$(field.Name : usesite).GetHashCode(); ]>
  }
      
  typeBuilder.Define(<[ decl: 
    public override GetHashCode() : int
    {
      mutable result = 0;
      ..$(fields.Map(make));
      result
    }
  ]>);
}
versus
mixin template ImplementGetSheeshCode() { 
    size_t GetSheeshCode()
    {
        alias T = typeof(this);
        size_t h = 123;        
        foreach(m; __traits(allMembers, T))
            static if (m!="Monitor") {             
                static if (isIntegral!(typeof(__traits(getMember, T, m))))
                    h ^= __traits(getMember, T, m);
                else static if (__traits(hasMember, typeof(__traits(getMember, T, m)), "toHash"))
                    h ^= __traits(getMember, T, m).toHash;
            }            
        return h;
    }
}

 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.