ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Пятница
3 мая
965448 Топик полностью
fk0, легенда (17.12.2019 01:58, просмотров: 177) ответил fk0 на Oсталось только подумать, как сделать, чтоб развиртуализация таки происходила, иначе вариант с виртуальными функциями ничем принципиально не хуже. PS: по ссылке более другой вариант, без thiz (и не const уже).
Я был о gcc слишком плохого мнения. Прекрасно он всё развиртуализирует, лучше чем руками. Руками как раз не работает из-за стирания типа (при приведению к базовому типу информация теряется). Странное дело, получается развиртуализация работает https://coliru.stacked-crooked.com/a/a2ac64a3d031d058
через какой-то другой механизм, параллельный. Ей тип -- не важен. Если при ручном вызове указателя компилятор знает что там такой-то тип, что там у него const/constexpr у такого-то типа, значит там может быть только такое и никакого значения. То при автомагической развиртуализации тип уже всё равно какой, но где-то компилятор знает, что он в этом месте получается именно такой (и опять же, если вручную, то один static_cast всё ломает), потому, что знает что там this -- именно такой, и никакой другой. Но есть ещё один ньюанс -- static перед CreateThread(). Без него опять не развиртуализирует, но уже по другой причине -- вынужден генерировать функцию на все случаи жизни (со static видит, что её вызовут только с такими-то аргументами, а не с чем угодно). На самом деле, я думаю, автору вопроса -- всё равно, несколько вызовов функций мало что изменят. Просто вот ответ на вопрос, что нужно для развиртуализации: или конкретное известное, считай константное, значение this (если virtual), или ни в коем случае не утерянная информация о типе (если CRTP и т.п.) Последний случай более надёжен, только вся программа получается -- шаблон. #include <stdio.h> #include <stddef.h> #include <array> // Base class, which will be passed to CreateThread() function. class ThreadBase { public: virtual size_t stack_size() const noexcept = 0; virtual void *stack_base() const noexcept = 0; virtual void run() = 0; }; static void CreateThread(ThreadBase &thread) { printf("creating stack of size %lu bytes at %p\n", long(thread.stack_size()), thread.stack_base()); thread.run(); } // Particular Thread implementation, parametrized by stack size. template <size_t SIZE> class ThreadImpl : public ThreadBase { private: mutable std::array<int, SIZE> stack; public: constexpr ThreadImpl() : stack() {} constexpr size_t stack_size() const noexcept /*final*/ { return SIZE; } void* stack_base() const noexcept /*final*/ { return &stack[0]; } void run() /*final*/ { puts("thread run()"); } }; ThreadImpl<42> thread_info; int main() { CreateThread(thread_info); return 0; }
[ZX]