@ProCxx

Страница 2344 из 2477
Yarique
12.09.2018
17:43:17
Множественное наследование- 2

Одна если virtual наследование

Anatoly
12.09.2018
17:45:41
компилятор утверждает, что Foo в Derived не реализован
struct IBase { virtual void Foo() = 0; }; struct IDerived : public virtual IBase { virtual void Bar() = 0; }; class Base : public virtual IBase { virtual void Foo() { } }; class Derived : public Base, public IDerived { virtual void Bar() { } }; IDerived* Create() { return new Derived(); }

Google
Yarique
12.09.2018
17:45:53
Два смещения в 2х таблицах виртуальных функций должно быть, компилятор не понимает где взять 2е - вот и ошибка

Nikita
12.09.2018
17:46:06
кастую к конкретному интерфейсу и отдаю наружу

снаружи её НЕ плюсовый код читает

у меня тут ручная реализация COM в clang на макоси

не спрашивайте зачем, так надо

Nikita
12.09.2018
20:00:31
В общем, раскровило всё

У интерфейсов с наследованием через public virtual другой формат vtable

и что с этим делать не понятно

Igor
12.09.2018
20:10:33
В общем, раскровило всё
Тупой вопрос - зачем наследоваться от интерфейсов виртуально? Виртуально есть смысл наследоваться от классов с данными чтобы не дублировать их.

В общем, раскровило всё
Проблемы с кастингом конечно могут быть к базовому интерфейсу если он наследуется много раз.

Google
Nikita
12.09.2018
20:21:58
при этом есть класс Foo, реализующий IFoo

если сделать класс Bar, наследующий Foo и пытающийся реализовать IBar

компилятору становится плохо

Igor
12.09.2018
20:27:07
иерархия интерфейсов вида IUnknown -> IFoo -> IBar
Ну сделайте тривиальные форвардеры если нужна предсказуемая таблица виртуальных функций? https://gcc.godbolt.org/z/FpINkq - пример от Анатолия без виртуального наследования.

иерархия интерфейсов вида IUnknown -> IFoo -> IBar
В целом же в COM ситуация такая же, но виртуальное наследование никто обычно не применяет. В ATL для борьбы с этим куча шаблонных хелперов :)

Igor
12.09.2018
20:34:56
Например IUnknown реализуется в CComObject, который параметризуется пользовательским классом.

Alex Фэils?︙
12.09.2018
20:37:03
Max
12.09.2018
20:44:49
Тупой вопрос - зачем наследоваться от интерфейсов виртуально? Виртуально есть смысл наследоваться от классов с данными чтобы не дублировать их.
Наоборот, нужно очень хорошо подумать, перед тем как наследоваться от данных. В большинстве случаев в такой ситуации лучше предпочесть композицю. А наследование интерфейсов позволяет отделить логику от собственно реализаций. Фигачишь логику с интерфейсами, и не паришься. Потом переезд на другие протоколы, новую бд, новую схему взаимодействия, и всё такое остаётся лишь вопросом имплементации конкретных интерфейсов.

Max
12.09.2018
20:48:01
так-то да, костыль костёлём погоняет.

Прогоню ереси: А хорошо в других языках придумали. Множественно наследуемся только от интерфейсов, а имплементации выносим отдельно. Вот бы и в ццп так.

Max
12.09.2018
20:52:49
оффтоп_мод_офф

Дык так тоже можно в цпп ж
можно.. Но только когда сам :)

Дык так тоже можно в цпп ж
У человека вот проблема на полдня

Alex Фэils?︙
12.09.2018
20:53:19
Да жди метаклассов чо

Igor
12.09.2018
20:54:18
Да жди метаклассов чо
Метаклассы не помогут, это синтаксический сахар.

Google
Max
12.09.2018
20:54:18
так жду, да =)

Max
13.09.2018
07:42:39
я не сталкивался с ситуацией, когда ромбовидное наследование реализаций было бы необходимо или удобно. А вот на проблемы с этим натыкался.

Max
13.09.2018
07:44:57
Ilia
13.09.2018
07:45:06
Потоки ввода-вывода...

Max
13.09.2018
07:46:25
Потоки ввода-вывода...
и в каком месте там необходимо ромбовидное наследование реализации?

Dmitry
13.09.2018
07:48:32
Всем привет такой вопрос. Можно ли перебрать одновеменно два вектора примерно таким образом? for (auto var1, auto var2 : vector1, vector2) {}?

Ilia
13.09.2018
07:49:01
я не сталкивался с ситуацией, когда ромбовидное наследование реализаций было бы необходимо или удобно. А вот на проблемы с этим натыкался.
Вообще, очень странно даже читать такое. Я вообще в упор не понимаю, почему тонкости наследования должы быть как-то связаны с наличием или отсутствием данных в классе... Также, совсем не понимаю, почему нужно себя ограничивать линейным, единичным наследованием. Мир гораздо разнообразнее. Удалось тебе уложиться в линейную иерархию -- ну, очень здорово, классно! Я не буду форсить множественное наследование специально, чисто ради искусства. Но вот если НЕ удалось, что тогда ?

и в каком месте там необходимо ромбовидное наследование реализации?
Ну, изучи, исследуй, материалы знаешь где, наверное?

Igor
13.09.2018
07:49:29
Dmitry
13.09.2018
07:49:59
Спасибо за ответы, почитаю

Igor
13.09.2018
07:50:58
Это же в boost, да ?
не только, в Ranges-v3 помоему тоже есть, и гугл по запросу zip_iterator ещё всякую мелочёвку выдаёт

Anatoly
13.09.2018
07:51:37
и в каком месте там необходимо ромбовидное наследование реализации?
Базовый класс потока, поток ввода, поток вывода, поток ввода вывода. Ты как Страуструпа не читал.

Max
13.09.2018
07:52:35
Базовый класс потока, поток ввода, поток вывода, поток ввода вывода. Ты как Страуструпа не читал.
читал. И код смотрел. Оно там есть, но не вижу в нём необходимости

Google
Ilia
13.09.2018
07:54:47
Всем привет такой вопрос. Можно ли перебрать одновеменно два вектора примерно таким образом? for (auto var1, auto var2 : vector1, vector2) {}?
Ну и напомню, что всё ещё можно написать простой цикл на основе индекса, а также использовать std::for_each + std::distance + std::advance. Последнее,конечно, по-уродски...

Dmitry
13.09.2018
07:56:41
А BOOST_FOREACH зачем?
Пока только такое нашел по своему запросу

Ilia
13.09.2018
07:57:13
Dmitry
13.09.2018
07:57:55
range-for используй или std::for_each.
Хорошо, сейчас почитаю. Спасибо еще раз)

Ilia
13.09.2018
07:58:33
Но вообще, ставь буст, алгоритмы, рэнжы...

Igor
13.09.2018
07:59:38
Решил попробовать такое BOOST_FOREACH(boost::tuple<int,int> &p, zip_range(v1, v2)) { doSomething(p.get<0>(), p.get<1>()); }
если 17е плюсы, то с помощью structured bindings можно делать так: { auto [index, value] = p; doSomething(index, value); }

Igor
13.09.2018
08:02:34
for (const boost::tuple<int,int> &p : zip_range(v1, v2)) { auto [index, value] = p; doSomething(index, value); } доволен?)

кстати так ещё нельзя? for (auto [index, value] : zip_range())

Косов
13.09.2018
08:03:39
Всем привет такой вопрос. Можно ли перебрать одновеменно два вектора примерно таким образом? for (auto var1, auto var2 : vector1, vector2) {}?
А ты уверен, что это действительно нужно? Какая задача изначально? Зачем ты их перебираешь?

Dmitry
13.09.2018
08:04:35
А ты уверен, что это действительно нужно? Какая задача изначально? Зачем ты их перебираешь?
Есть два вектора, их надо перебрать и сделать определенные действия над каждым элементом. Сейчас для этого есть два цикла. Я хотел это как то склеить

Александр
13.09.2018
08:05:18
почему два, если один цикл должен быть?

Max
13.09.2018
08:05:26
Вообще, очень странно даже читать такое. Я вообще в упор не понимаю, почему тонкости наследования должы быть как-то связаны с наличием или отсутствием данных в классе... Также, совсем не понимаю, почему нужно себя ограничивать линейным, единичным наследованием. Мир гораздо разнообразнее. Удалось тебе уложиться в линейную иерархию -- ну, очень здорово, классно! Я не буду форсить множественное наследование специально, чисто ради искусства. Но вот если НЕ удалось, что тогда ?
ну я не только про данные. Данные — это так, индикатор, что пора задуматься, а не пытаешься ли ты натянуть стул на осла, из-за того, что у них по четыре ноги. Я больше про реализации. И там тонкости наследования и так очень зависят, вот например в случае разных реализаций с одинаковым интерфейсом. Короче, топлю за композицию реализаций. Интерфейсы смешиваешь как угодно, а реализации хранишь где-то отдельно. Так прозрачнее и более поддерживаемо.

Dmitry
13.09.2018
08:05:38
почему два, если один цикл должен быть?
ПОтому что два вектора перебираются отдельно

Александр
13.09.2018
08:06:05
по-моему, проще оставить 2 цикла..

или там действия одинаковые?

Dmitry
13.09.2018
08:06:45
или там действия одинаковые?
Да, просто векторы разные

Александр
13.09.2018
08:07:15
тогда нужен не zip, а какой-нибудь concat, который из двух векторов клеит новый вектор без копирования

Google
Александр
13.09.2018
08:07:36
или проще: вынести тело цикла в лямбду и сделать два цикла/два for_each

Ilia
13.09.2018
08:07:43
for (const boost::tuple<int,int> &p : zip_range(v1, v2)) { auto [index, value] = p; doSomething(index, value); } доволен?)
Не, не доволен. Зачем тут это? Можно либо сразу тапл в функцию передавать либо in-place при вызове выделять его элементы ... Короче и яснее. Я думал, там сразу в for_each можно, так, как ты написал, что ещё нельзя.

Stolyarchuk
13.09.2018
08:08:20
почему два, если один цикл должен быть?
for (int i = 0, j = 0; i < v1.size() || j < v2.size(); i++, j++)

Anatoly
13.09.2018
08:09:22
for (int i = 0, j = 0; i < v1.size() || j < v2.size(); i++, j++)
for(size_t i = 0; i < std::min(v1.size(), v2.size()); ++i) ...

Александр
13.09.2018
08:09:27
zip нужен в тех случаях, когда у нас 2 последовательности одинаковой длины и нужно совершить действие над каждой парой

Igor
13.09.2018
08:11:51
Александр
13.09.2018
08:12:17
Косов
13.09.2018
08:13:08
Dmitry
13.09.2018
08:14:17
О, вы тут еще об этом говорите. Решили с коллегами оставить текущее решение с двумя циклами (не знаю почему, я просто ревьюил)

Косов
13.09.2018
08:15:26
О, вы тут еще об этом говорите. Решили с коллегами оставить текущее решение с двумя циклами (не знаю почему, я просто ревьюил)
Правильное решение, два цикла читать удобнее. Если долго то можно один ассинхронно вычислять , пока второй считается

Страница 2344 из 2477