Здравствуйте, 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;
}
}