Constantine
фактически класс Derived при использовании конструктора 2 должен получить этот void*
Constantine
все равно должен
Constantine
все равно любой код, вызывающий этот конструктор, обязан знать этот void*
Александр
Должен. Вот он получает его еще до того, как сам сконструировался
Constantine
да, но получается, что выставляется требование проинициализировать Base перед вызовом конструктора
Constantine
а это то же самое, что передать Base* в кажестве параметра при агрегации
Александр
все равно любой код, вызывающий этот конструктор, обязан знать этот void*
Но если это будет шаблонная фабрика, скрытая в недрах библиотеки, то всё ок
Constantine
а в чем проблема шаблонной фабрики использовать способ 1?
Александр
В том, что она требует от Derived дополнительного параметра в конструкторе void* context
Constantine
я просто не могу никак понять, почему в данном случае _неявная_ передача параметра способом 2 вообще отличается от _явной_ способом 1, если параметр обязателен
Александр
Неявная передача параметра способом 2 делается внутри шаблонной фабрики и пишется один раз. А первый способ требует в каждом наследнике Base (пусть их 100) писать долбаный параметр в конструктор, который вообще является частью внутреннего интерфейса библиотеки
Constantine
понял
Constantine
мы хотим, чтобы класс Derived42 не знал про то, как инициализируется Base и что он вообще инициализируется
Александр
Ага
Constantine
но при этом хочет его использовать
Constantine
а нельзя сделать параметр конструктора отдельным типом?
Constantine
и разрешить неявное преобразование дабла?
Александр
Во-первых, конструктор там будет иметь любое кол-во аргументов
Александр
Про неявное преобразование не понял
Constantine
ну я пишу
Constantine
Derived(base_constructor_arguments_type a)
Constantine
и разрешаю base_constructor_arguments_type(double)
Александр
о_О
Александр
Зачем менять конструктор Derived?
Александр
А, и фабрика напрямую вызываться не будет, конечно
Александр
Она там внутри либы тоже болтается
Constantine
для того, чтобы выполнить два условия: одновременно получить только нужные параметры и при этом получить еще один неявно
Александр
А можно пример? Я всё равно не понимаю, в чём идея
Constantine
идея что вместо Derived(double, int) пишем сигнатуру Derived(helper<double, int>
Constantine
где helper на самом деле еще содержит контекст
Constantine
у меня пока возникла одна идея в случае агрегации: а нет гарантии, что если указано union{ Base* base; ??? }; то компилятор не будет инициализировать поле?
Александр
Ага, но пользователь опять расстроен, что ему придётся писать код
Александр
В чём моя фабрика-то неправильная?)
Александр
идея что вместо Derived(double, int) пишем сигнатуру Derived(helper<double, int>
А, и всё равно придётся это передавать в конструктор Base, о чем опять грустит юзер
Constantine
я подумал за логику и решил, что нельзя требовать с компилятора ничего не трогать в данном случае
Александр
Предполагаем, что в базовом классе только указатель и какие-нибудь int, double, char
Constantine
потому что переменная класса может быть объявлена в глобале, а у компилятора там обязанность все инициализировать
Constantine
емнип, конечно
Александр
😳😳
Александр
Чего? Это ж не статическое поле
Александр
Вот меня тоже только это смущает - что вызванный Base() по умолчанию потрёт контекст, записанный туда ранее
Constantine
на кого распространяется правило инициализации при объявлении в глобале? только на int всякие или на все объекты?
🐙 Antony
Есть вопрос к ненавистникам UB: http://cpp.sh/2rbzm внутри main()
Мракобесие... Не делайте так, у вас сойдут с ума санитайзеры и оптимизатор. Вам необходимо передавать контекст внутрь базового класса так, чтобы Derived ничего не знал об этом? Создайте в базовом классе private: static thread_local void* ctx; static void* get_context(); static void set_context(void*); Явно вызывайте get_context() в конструкторе базового. Сделайте frined template <class Derived> factory_method; внутри базового, в фабрике делайте set_context(); Но всё это выглядит как-то болезненно и неправильно, буд-то что-то неправльно с иерархией классов... Кстати, посмотрите библиотеку DI https://github.com/boost-experimental/di она решает вашу проблему
Constantine
просто если такое правило распространяется на все объекты, я не верю, что стандарт требует, что инициализация блока памяти произойдет НЕ в момент вызова конструктора
Constantine
то есть здесь моя "Б. Логика" требует, чтобы случай, когда конструктор явно не инициализирует переменные, считался UB
Constantine
это неявная передача параметра как раз
Александр
С DI придётся юзера заставлять что-то писать (совсем не простое)
Александр
это неявная передача параметра как раз
Если имелось в виду это, то прошу прощения, не понял
Constantine
да не, я почему-то не подумал, что можно в действительности ЯВНО написать НЕЯВНУЮ передачу параметра через thread_local
Александр
Да thread_local можно было бы потом прикрутить, когда я вспомнил бы о потоках
Constantine
интересно, у вижака есть известный мне note, распространяется ли он на thread_local
Constantine
On Windows operating systems before Windows Vista, __declspec( thread ) has some limitations. If a DLL declares any data or object as __declspec( thread ), it can cause a protection fault if dynamically loaded. After the DLL is loaded with LoadLibrary, it causes system failure whenever the code references the __declspec( thread ) data. Because the global variable space for a thread is allocated at run time, the size of this space is based on a calculation of the requirements of the application plus the requirements of all the DLLs that are statically linked. When you use LoadLibrary, you cannot extend this space to allow for the thread local variables declared with __declspec( thread ). Use the TLS APIs, such as TlsAlloc, in your DLL to allocate TLS if the DLL might be loaded with LoadLibrary.
🐙 Antony
Неазчто :)
🐙 Antony
интересно, у вижака есть известный мне note, распространяется ли он на thread_local
Да, распространяется и на thread_local. Немного вот тут описана печаль: http://www.boost.org/doc/libs/1_64_0/doc/html/boost_dll/missuses.html А именно: Issue: Thread local storage seems to be corrupted. Fix: Some platforms have no out-of-the-box support for plugins that use TLS, for example Windows. Use platform specific workarounds or just do not use TLS in plugins.
Constantine
я так и подозревал 😢
🐙 Antony
Но вы эту проблему заметите только если ручками подгружаете библиотеку (используете плагины). Если вы библиотеку прилинковали - то всй нормально.
Constantine
спасибо за заботу :) я не первый день в вин разработке, так что в целом понятен текст, который пишут на MSDN :)
Constantine
собственно, я знаю, потому что у нас используется thread_local и это ограничение к dll в хелпе приписано
🐙 Antony
спасибо за заботу :) я не первый день в вин разработке, так что в целом понятен текст, который пишут на MSDN :)
:) Мне он всегда не понятен. Приходится вдуплять по часу на каждую страницу
🐙 Antony
Constantine
при этом можно неплохо огрести, например, SetWindowsHookEx не с _LL будет подгружать библиотеку через LoadLibrary
Anonymous
Обсуждение IDE - в #supapro.
Constantine
флудить-то не запрещайте мимими
Vladislav
Холивары - в @pro.cxx.holywars)
Vladislav
#holywar
Constantine
вообще, ловите идею: автоматически синтезировать подконфу для обсуждения тем
Constantine
собственно, у меня нет идей как по-другому не превращать любую конфу во <s>флуд</s> объяснение, как работает std::move
Александр
:D
🦥Alex Fails
#chatlist
🦥Alex Fails
вот вам набор ссылок
Vladislav
Мафии нету
🦥Alex Fails
какая к дьяволу мафия с открытым инвайтом? ;)
Constantine
у нас в универе кружок по программированию 80% времени это мафия с открытым инвайтом :)