Size: a a a

2021 July 06

A

Alex Ф-ф-фэils!🌠︙... in supapro.cxx
дык поэтому я и ругался
источник

d

d7d1cd in supapro.cxx
Понял, не увидел сразу
источник

DR

Denys Romanov in supapro.cxx
Есть следующее:

struct Mother
{
   virtual void f() {}
};

struct Father
{
   virtual void g() {}
};

struct Child : Mother, Father
{
};

В памяти объект типа Child будет таким: [Mother::vptr][Father::vptr].

Вопрос: когда происходит каст к указателю/ссылке одного из родителей этого объекта, то при вызове виртуальной функции через указатель/ссылку компилятор как-то распознает по какому из 2ух указателей нужно обратится к нужной vtable или как-то по другому происходит?
источник

d

d7d1cd in supapro.cxx
Куда кастуют, метод того класса и вызывается. У тебя в чилде не переопределен f
источник

DP

Denis Paukaev in supapro.cxx
Ну так если каст к предку то сразу понятно какую втбл брать же
источник

DR

Denys Romanov in supapro.cxx
Не обязательно, у родителей есть
источник

d

d7d1cd in supapro.cxx
И? Тут даже виртуальность f и g значения не имеет, ибо они не переопределены в ребенке.
источник

DR

Denys Romanov in supapro.cxx
Я не понял как это происходит на более низком уровне. Как компилятор организовывает обращение по нужному указателю к vtable, на основе порядка указания родителей при объявлении потомка(индексируя поля объекта в памяти) или как?
источник

C

Chuvi in supapro.cxx
Сильно зависит от компилятора и от платформы. Стандартом  языка это не определено
источник

DR

Denys Romanov in supapro.cxx
Для примера этого достаточно. Хоть в потомке нет переопределений, vtable все равно будет, хоть такая же как и у родителей
источник

DP

Denis Paukaev in supapro.cxx
Никто не говорит что не будет
источник

d

d7d1cd in supapro.cxx
Тут нет магии. В матери и в отце есть по указателю на свою таблицу виртуальных функций. Когда ты создаёшь ребенка, то у него есть оба этих указателя. Так как в ребенке не переопределены методы родителей, то в таблицах хранятся указатели на методы родителей. При касте ребенка к одному из родителей, указатель на таблицу другого родителя теряется. Сделав каст ребенка к матери, ты не сможешь вызвать метод отца.
источник

DR

Denys Romanov in supapro.cxx
Именно «теряние» меня и интересовало, и как понял от компилятора и платформы зависит его реализация
источник

DP

Denis Paukaev in supapro.cxx
Там даже само наличие таблицы деталь реализации
источник

DP

Denis Paukaev in supapro.cxx
Просто так везде сделали, но вообще стандарт тут ничего не регламентирует
источник

DR

Denys Romanov in supapro.cxx
Понятно, спасибо
источник
2021 July 07

G

Gabriel in supapro.cxx
Парни, такой вопрос. Есть такой код:
template <typename S, typename... Handlers>
auto makeTokenBuilder(Handlers&&... h)
{
   return TokenBuilder<S, std::decay_t<Handlers>...>{std::forward<Handlers>(h)...};
}
....
  auto tokenBuilder = makeTokenBuilder<std::tuple<BuildHeader, BuildPayload, BuildSignature>>
   (
       [](BuildHeader& s, GetHeader event) -> TransitionTo<BuildPayload>
       {
           return {};
       },

       [](BuildPayload& s, GetPayload event) -> TransitionTo<BuildSignature>
       {
           return {};
       },
       
       [](BuildSignature& s, GetSignature event)
       {
       }
   );

Но когда я хочу получить тип переменной tokenBuilder(делаю это так  using Type = decltype(tokenBuilder);), то получаю ошибки типа:
"Utility::getTokenBuilderAndFinaleJSON::<lambda_a3402f3ac019ea93ae7bf5f4fba2c32d>::<lambda_a3402f3ac019ea93ae7bf5f4fba2c32d>(void)": предпринята попытка ссылки на удаленную функцию

Знает кто как можно получить тип?
источник

SS

Sergey Sobolev in supapro.cxx
Ты случайно не через gcc компилишь? Вот те символы, которые линкер не может найти относятся к механизму исключений в с++
источник

SS

Sergey Sobolev in supapro.cxx
Через gcc точно не надо
источник

SS

Sergey Sobolev in supapro.cxx
А компилишь руками? Полная команда какая у g++?
источник