MrShoor
> не хочется заводить отдельно вектор указателей.
А что не так? Ты ведь сам указал вектор в наборе условий.
Der FlugSimulator
> А что не так? Ты ведь сам указал вектор в наборе условий.
Я предполагал что что-то типа вектора будет овнить поля, а полей не будет. std::tuple бы идеально подошел, но по нему нельзя итерироваться из переменной.
MrShoor
> но по нему нельзя итерироваться из переменной.
можно
MrShoor
А просто проитерироваться по всем элементам std::tuple не подойдёт?
Например так:
template <typename TupleType, typename Functor> inline void for_each_tuple_element(TupleType&& tuple, Functor&& func) { std::apply( [&func]( auto& ...x) { ( ..., func( x)); }, tuple); } // usage for_each_tuple_element( my_tuple, []( auto& tuple_element) { // do stuff });
Вариант с std::variant, который предложили выше - не zero-cost.
MrShoor
> class Foo {
> private:
> BaseT<Bar1> m_bar1;
> BaseT<Bar2> m_bar2;
> BaseT<Bar3> m_bar3;
> BaseT<Bar4> m_bar4;
> BaseT<Bar5> m_bar5;
> public:
> std::string ToString() const {
> return m_bar1.ToString() + m_bar2.ToString() + m_bar3.ToString() +
> m_bar4.ToString() + m_bar5.ToString();
> }
> };
Maximum govnocpp.
Могу ещё предложить X macro:
#define BARS \ X(Bar1, m_bar1) XSEP \ X( Bar2, m_bar2) XSEP \ X( Bar3, m_bar3) XSEP \ X( Bar4, m_bar4) XSEP \ X( Bar5, m_bar5) class Foo { private: #define X( t, n) t n; #define XSEP BARS #undef X #undef XSEP public: std::string ToString( ) const { return #define X( t, n) n.ToString( ) #define XSEP + BARS #undef X #undef XSEP ; }
Alexander K
> Вариант с std::variant, который предложили выше - не zero-cost.
потому что вариант это тяжелая артиллерия когда тебе нужна свобода в рантайме в том числе. Будет возможность добавить/удалить данные из вектора.
Aroch
> держи https://godbolt.org/z/6jsMEdaez
> если же хочешь через tuple, то смотри в сторону std::apply
std::variant - это перебор
Alexander K
> А просто проитерироваться по всем элементам std::tuple не подойдёт?
>
> Например так:
Подойдет. Спасибо за вариант с std::apply. Выглядит круто и как то, что надо.
Имбирная Ведьмочка
> Могу ещё предложить X macro:
Неее, макросы я и сам могу, но не хочу загрязнять ими код.
В общем на минимальных классах std::tuple работает, но теперь entt подкинул крестопроблем.
Вот этот код не компилируется:
#include <entt/entt.hpp> #include <tuple> struct Cmp1 { }; template<typename T> struct AA { entt::registry& reg; entt::observer obs{ reg, entt::collector.update<T>() }; AA( entt::registry& reg) : reg( reg) {} }; struct BB { entt::registry& reg; AA<Cmp1> aa{ reg }; std::tuple<AA<Cmp1>> tpl{ AA<Cmp1>{reg} }; BB( entt::registry& reg) : reg( reg) {} }; void main( ) { entt::registry r; BB b( r); }
С вот таким сообщением:
error C2665: 'std::tuple<AA<Cmp1>>::tuple': no overloaded function could convert all the argument types message : could be 'std::tuple<AA<Cmp1>>::tuple(std::tuple<AA<Cmp1>> &&)' message : 'std::tuple<AA<Cmp1>>::tuple(std::tuple<AA<Cmp1>> &&)': cannot convert argument 1 from 'AA<Cmp1>' to 'std::tuple<AA<Cmp1>> &&' message : Reason: cannot convert from 'AA<Cmp1>' to 'std::tuple<AA<Cmp1>>' message : No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called message : or 'std::tuple<AA<Cmp1>>::tuple(const std::tuple<AA<Cmp1>> &)' message : 'std::tuple<AA<Cmp1>>::tuple(const std::tuple<AA<Cmp1>> &)': cannot convert argument 1 from 'AA<Cmp1>' to 'const std::tuple<AA<Cmp1>> &' message : Reason: cannot convert from 'AA<Cmp1>' to 'const std::tuple<AA<Cmp1>>' message : No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called message : or 'std::tuple<AA<Cmp1>>::tuple(std::allocator_arg_t,const _Alloc &,std::pair<_First,_Second> &&)' и тут еще куча строк что во что оно пыталось сконвертировать.
Опытным путем устновил, что если закомментировать
entt::observer obs{ reg, entt::collector.update<T>() };
То всё компилируется.
Либо компилируется с entt::observer, но если закомментировать строку:
std::tuple<AA<Cmp1>> tpl{ AA<Cmp1>{reg} };
Т.е. по факту обзервер оно может создать, но только если оно лежит в поле класса: AA<Cmp1> aa{ reg };
Но не может сконструировать tuple пока там есть observer.
Если лезть в observer, то он объявлен так:
using observer = basic_observer<registry>;
Вот basic_observer: https://github.com/skypjack/entt/blob/2f51341633aba7a37af9208af80… rver.hpp#L161
А вот basic_storage: https://github.com/skypjack/entt/blob/e48817d518c0ada57665be07ba9… rage.hpp#L231
А вот basic_sparse_set: https://github.com/skypjack/entt/blob/e48817d518c0ada57665be07ba9… _set.hpp#L170
И для меня тут темная магия понять, почему оно не компилируется...
Я не уверен, но, возможно, ты пытаешься скопировать или переместить экземпляр АА, а в нем ссылка, которая не даёт создать конструктор копирования или перемещения по умолчанию. Но это нужно проверять.
Went
> Я не уверен, но, возможно, ты пытаешься скопировать или переместить экземпляр
> АА, а в нем ссылка, которая не даёт создать конструктор копирования или
> перемещения по умолчанию. Но это нужно проверять.
Проблема не в ссылке, т.к. при наличии ссылки всё конструируется. Не конструируется при наличии entt::observer внутри АА
upd. Да, проблема в констуркторах, которые удалены в entt::observer. Теперь собсна вопрос, как создать std::tuple как поле класса, если конструкторы удалены?
MrShoor
> Bar1, Bar2, Bar3 - не имеют никакого общего предка.
Значит сделай его. Тебе полюбому прийдется сделать общий интерфейс сериализабле.
Эта проблема решается запросто, пилишь кодоген с рефлексией на констекспр и радуешься. Почти такой уже запилили назвали протобуфом, всебы хорошо, но на плюсах вместо простых структур, неудобоваримое г.
samrrr
> проиобуфом
*protobuf - если кто не знает заранее, по твоему названию не сможет даже в гугле найти.
Имбирная Ведьмочка
Ок пусть будет протобуф.
Вообще гугл и так схавает https://www.google.com/search?q=%D0%BF%D1%80%D0%BE%D0%B8%D0%BE%D0… rome&ie=UTF-8
samrrr
> Почти такой уже запилили назвали протобуфом
Собственно вышеописанный сабж и возник из-за попыток подружить protobuf с темплейтами от entt.
MrShoor
> Собственно вышеописанный сабж и возник из-за попыток подружить protobuf с
> темплейтами от entt.
А чо, мету неосилил?