Ioann_
Нет, я про реальные случаи где сие нужно :?
Constantine
это реальные случаи
Constantine
я могу примеры классов Interface/Implementation/Base/Derived подбросить
Ioann_
Да то что они реальные я понял, объясни почему именно так а не иначе
Ioann_
Почему не хочется возвращать именно base
Constantine
например, Interface это общий базовый класс комбобоксов, Implementation это его реализация для ColorPicker, которая агрегирует Derived (дропдаун комбобокса выбора цвета), который наследует Base (дропдаун комбобокса)
Aidar
Чекаешь
Aidar
Кидаешь еррор
Constantine
Ну и что
Это должно работать для incomplete предка
Aidar
Ну тогда не кидаешьеррор
Constantine
Т.е. там требование должно быть в духе "единственный public base в definition"
Aidar
Можно какое-нибудь гарантирование порядка сделать
Aidar
И разрешить только н первых
Constantine
Если наследование, то должно быть "до первого incomplete type"
Aidar
Последний можно инкомплит
Constantine
Ну компилятор может сгенерировать QueryInterface вплоть до первого Incomplete Type в описании
Aidar
Ну вот я о том же
Aidar
Только дико сложно выходит
Aidar
Яб на таком писать не стал
Ioann_
Ну вот я понял идею, но как по мне слишком запутанно, да и не могу говорить что в самом коде не приведет к путаннице
Constantine
Ну вот я понял идею, но как по мне слишком запутанно, да и не могу говорить что в самом коде не приведет к путаннице
Поэтому такая декларация должна по-хорошему явно отличаться от ошибки "забыли пустое тело класса"
Aidar
Ну хз
Aidar
Это же одно и то же как по мне
Aidar
Кто ваще такие ошибки делает
Matwey
Извините что отвлекаю вас от важного спора, я просто тут подумал
Constantine
Я :)
Aidar
Да и не даст ничего
Aidar
Пусть не отличается ошибка останется же
Constantine
Постоянно std::true_type наследую без тела класса
Aidar
А поведение не поменяется
Constantine
Ошибки не будет, если не будет явного различения
Aidar
Компилятор выдаст
Aidar
При обращении к классу
Aidar
А поведение не поменяется же
Constantine
Короче я бы хотел явное слово в таком объявлении, но я не могу его придумать
Constantine
Хоть : final
Matwey
Разве в современном стандарте разрешено неявно приводить указатель на функцию Deriv* (*fun)() к Base* (*fun)() лишь на том основании, что Deriv* приводится к Base*?
Constantine
Разве в современном стандарте разрешено неявно приводить указатель на функцию Deriv* (*fun)() к Base* (*fun)() лишь на том основании, что Deriv* приводится к Base*?
Я могу ошибаться, мне казалось, что указатель на функцию не приведется, кроме точного соответствия всех типов
Matwey
Вот тот пример выше подразумевает это
Matwey
Я имею ввиду, чем виртуальные функции хуже/лучше просто указателей на функции?
Constantine
Проблема в том, что The class in the return type of Derived::f must be either Derived itself, or must be a complete type at the point of declaration of Derived::f.
Matwey
А почему не разрешить тоже самое для простых указателей на функции?
Matwey
Ну, кроме того, что ими никто не пользуется...
Constantine
А почему не разрешить тоже самое для простых указателей на функции?
Потому что на самом деле происходит хитро выполненный тайпкаст возвращаемого значения
Constantine
Я могу представить себе две реализации, и обе они требуют знания цепочки наследования
Matwey
Чем он хитрее Base* x = new Deriv();?
Constantine
Это он и есть
Constantine
Вы же понимаете, что это выражение может требовать вычисления?
Constantine
Как правило, реализация при выполнении QueryInterface выполняет смещение указателя
Constantine
В частности, стандарт C++ НЕ гарантирует следующее: Derived * p = nullptr; Base * p2 = p; assert(p2 == nullptr); //failed. нет гарантий
Constantine
И не может этого гарантировать в случае, если у Derived более одного предка
Constantine
В случае с наследованием виртуальных функций компилятор может проследить всю необходимую цепочку преобразований
Matwey
А
Matwey
понял
Constantine
Например, он может считать, что функция всегда возвращает Base* и у потомка делать static_cast соответственно на Base* и Derived*
Constantine
И все упирается в то, что я не могу в случае incomplete type указать компилятору, как выполняется этот static_cast
Matwey
да, я понял, что проблема в том, что static_cast от двух типов зависит
Matwey
ну как проблема, не проблема, а мир так устроен
Constantine
это на самом деле весьма неприятное неудобство, что нужно при наследовании писать final на старую функцию, новую virtual функцию и перевызов
Constantine
либо включать определение Derived
Matwey
ну так это самое, если тип incomplete, то ни о каких вычислениях при Base* x = new Deriv(); уже нет смысла говорить. единственное, что можно предложить - просто записать указатель как есть. потому-что располажение в памяти неизвестно
Matwey
как в случае простого немножественного наследования
Constantine
так речь идет о том, чтобы указать компилятору, что это преобразование тривиально, без определения класса
Matwey
но так почему бы не разрешить приведение указателей на функцию, если мы уже рассказали компилятору, что преобразование тривиально?
Ioann_
А потом что то поменяется ...
Constantine
А потом что то поменяется ...
В точке определения класса видно, что декларация ошибочна
Matwey
ну, т.е., допустим, мы рассказали...
Constantine
На самом деле достаточно даже перенести проверку на определение функции в первом примере
Matwey
Но тогда придется каждую фукнцию помечать
Ioann_
Кстати, а безопасно ли поинтер на инт приводить к поинтеру на уинт ?
ඞ
Они же итак инт
ඞ
ой блять
Ioann_
Я про стрикт альясинг если что говорю
ඞ
Если у тебя функция вернёт -1, то нужно проверять
ඞ
А то получится дыра