C++
IT-стандарты
Компиляторы
Комментарии 23
-17
Давно уже пора выкинуть С++ на свалку истории. Хватит уже этого франкинштейна качать.
0
На плюсах можно вполне читаемо и адеквато писать. Другое дело что этому нигде не учат.
+4
{sarcasm}*Комментарий про Rust*{/sarcasm}
А если серьезно, то отличные новости! Может наконец в с++ появится какой-то юзабельный стандартный reflection и семантика для пропертей. Может я не в курсе, но кто сегодня использует c++ там, где нужно писать на C? ИМХО, эта совместимость уже давно себя изжила.
0
Тоже не хватает этих возможностей в C++. На текущий момент неплохо получается реализовать properties с помощью visit_struct. Сделал runtime обертку для себя, так что при необходимости runtime reflection тоже работает. Плюс автор обещал подумать над совместимостью с cereal. В результате получается неплохая комбинация: static reflection + runtime reflection + serialization. И для всего этого достаточно одного макроса:
struct my_type {
  int a;
  float b;
  std::string c;
};

VISITABLE_STRUCT(my_type, a, b, c);

либо
struct my_type {
  BEGIN_VISITABLES(my_type);
  VISITABLE(int, a);
  VISITABLE(float, b);
  VISITABLE(std::string, c);
  END_VISITABLES;
};

И затем:
visit_struct::for_each(my_struct,
    [](const char * name, const auto & value) {
      std::cout << name << ": " << value << std::endl;
    });
std::cout <<visit_struct::get<3>(s);
auto variant=visit_struct::get(3,s);

и т.д.
0
Вы вполне могли-бы перенести этот функционал в рантайм (используя std::tuple к примеру), вместо этапа компиляции. Или у вас есть пример отличный от:
std::cout <<visit_struct::get<3>(s);
auto variant=visit_struct::get(3,s);
который требуется на этапе компиляции?

В чём смысл запутывания кода с помощью visit_struct, если используется это в рантайме?
0
Я не совсем понимаю, что Вы имеете ввиду, под «можно перенести это в рантайм испульзуя tuple»? Смысл в том, что с помощью одной и той же «аннотации» можно получить одновременно и compile time и runtime reflection. Затем, где можно, используется compile-time рефлексия, а где нельзя — runtime через std::variant. Runtime вариант — это аналог Qt Property. Мне кажется, что если при прочих равных compile time reflection лучше runtime т.к. работают проверки компилятора (меньше ошибок) и эффективней (лучше производительность).
struct S {
    int n;
    float f;
    std::string filler;
    char c;
    float ff;
};
VISITABLE_STRUCT(S, n, f, c,ff);


int main()
{
    S s{42,3.14f,"test",'Z',999.9};
    auto printer=[](auto&& v) {
        std::cout<<v<<'\n';
    };
    visit_struct::to_variant<S>::type var;
    //static_assert(std::is_same<var_type,decltype(var)>::value, "" );
    var=visit_struct::get_variant(2,s);
    std::visit(printer,var);

    var.emplace<3>(2.718f);
    visit_struct::set_field(3,s,var);
    var=visit_struct::get_variant(3,s);
    std::visit(printer,var);
    
    for (int i=0; i<visit_struct::field_count<S>(); ++i)
      std::cout<<visit_struct::get_name<S>(i)<<' ';
    std::cout<<'\n';
    return 0;
}
Z
2.718
n f c ff
0
Ну пример в принципе тот-же самый. Обращение к члену структуры по порядковому номеру, с автоприведение типов (std::tuple). В отличии от std::tuple, можно получить имя по индексу (наверное тут наибольший профит в удобстве?). Использование этого имени (например сравнение), — уже рантайм. Также как впрочем и с tuple. Обращение по индексу — генерация кода (как и в tuple). При этом использование структуры (обращение по имени), — compile time (заметьте без дополнительной генерации кода).

Это не троллинг, я реально не могу вкурить приемущество использования приведённого вами метода.

Для примера, простыми словами, где использование приведённого вами метода предоставляет преимущества:
а) в лучшей производительности;
б) в читабельности кода;
в) в удобстве использования;
г) в конкретном прикладном случае;
0
Мне кажется, все пункты справедливы, от а) до г). Проблема с tuple в том, что члены не именованы. В принципе, можно было бы создавать tuple of references, не удивлюсь если под капотом visit_struct так и делает. В моём случае есть возможность комбинировать именованный доступ и доступ по индексу с минимально возможным в принципе оверхедом. Это читаемо и удобно, позволяет избегать дублирования кода, нет необходимости платить за то, что не используется.
Применение то же, что и для Qt Properties, BOOST_HANA_DEFINE_STRUCT, RTTR. Те применения, которые я использую — это разные формы сериализации по сути, как для сохранения на диск и передачи по сети, так и для GUI-редактирования объектов и их свойств. Сериализация может не требовать рантайм-рефлексии так как передавать всё равно весь объект разом. GUI-редактор требует рантайма т.к. опции изменяются в произвольном порядке, известном только в рантайме. Я нашел статью «Designing a C++ Property System» по этой теме, там и мотивация и проблемы рассматриваются.
0
а разве существуют задачи, где при наличии возможности писать на с++ НУЖНО писать на си?
+1
Есть слепые фанатики, которые на любой вопрос говорят «Да ну на* этот ваш {любой язык программирования}, мы сейчас все быстро и круто на C напишем!».
0
Да, это все задачи для встраиваемых девайсов с вычислительно слабыми микроконтроллерами, где писать на C++ теоретически можно, но столько памяти сжирает, что в итоге чаще пишут на С. Поэтому на месте С++-комитета я бы не отказывалась от совместимости, просто чтобы не оттолкнуть embedded-сообщество окончательно.
0
вы сначала говорите, что c++ непригоден для embedded’а, а сразу после утверждаете, что отказаться от совместимости с си плохо с точки зрения embedded. Определитесь уже.

Кстати, отмечу, что поддержка interoperability может быть реализована не только на уровне языка (как и для всех других пар языков). Например — на тех же модулях с явным указанием версии языка — то, о чем я писал ниже
+1
Если новые плюшки будут настолько несовместимы со старым кодом, что его нельзя будет подтянуть опциями, прагмами или дефайнами, то это потянет за собой разделение гораздо худшее, чем между Python 2 и 3.
0
Если тот же Python можно запускать только на конкретной версии интерпретатора, то в С++ разные модули наверняка можно будет билдить с разными флагами компилятора, а потом линковать вместе.
0
Это понятно, про это я и писал. Но вдруг допроектируются до таких изменений, которые, например, не дадут использовать классы из одних модулей в других.
+1
думаю, правильно, если вместо «версий стандарта» мы получим «версии языка». Пара breaking changes между c++11/14/17 все равно есть, так зачем тянуть устаревшие кодобазы в новый c++ если можно просто закрепить за ними версию языка?
0

Тут проблема в заголовочных файлах. Там везде нужно будет указать версию языка, иначе в другую версию они просто не пролезут, даже если останется двоичная совместимость

+1
это должно решаться модулями. В худшем случае, можно адаптировать существующий синтаксис: extern “c++17” {…
0
плохая идея, т.к. сейчас это конструкция — только совет для линкера.
-1
это не «совет», а явное указание контракта — «использовать сишный манглинг и соглашение о вызовах». По сути, extern «C» (с учетом того, как его используют) значит «вот этот вот код компилируй как будто он сишный»
Только полноправные пользователи могут оставлять комментарии. , пожалуйста.