Aidar
Треитсы
Aidar
Это фича а не ограничение
Constantine
Во! Придумал синтаксис. Хочу для виртуальных функций два дополнительных модификатора ref-значения static и constexpr.
struct base {
virtual int get_attribute() constexpr = 0;
};
struct derived : base {
virtual int get_attribute() constexpr override { return 1; }
};
Constantine
Модификатор 'static' означает, что в теле функции не определен this; модификатор 'constexpr' дополнительно означает, что сама функция должна быть constexpr
Александр
Constantine
В частности, модификатор 'static' не создает полноценно статическую функцию, он лишь гарантирует, что возвращаемое значение зависит только от динамического типа объекта
Constantine
В случае с constexpr компилятор имеет возможность вписать в таблицу виртуальных функций непосредственно результат вычисления constexpr выражения
Александр
usernameak
а есть
usernameak
а есть какой то враппер d3d9->opengl на линукс?
usernameak
мне чтобы не вайн
usernameak
только dx
Александр
Александр
Да и сейчас это всё реализуемо
Constantine
Это не обязательно const
Constantine
Constantine
И да, это не реализуемо без проверок
🐙 Antony
Не хочется портить вам счастье, но если объект содержит виртуальные функции, его нельзя сделать constexpr
Александр
Чем ломается?
Например, хранением в таблице виртуальных функций не функции, а значения
Александр
В текущем стандарте языка все эти хотелки и так работают, просто да, где-то лишний раз передаётся this, который фактически не требуется
Constantine
🐙 Antony
Constantine
struct base {
virtual int get_attribute() constexpr = 0;
};
//предложение
struct derived : base {
virtual int get_attribute() constexpr override { return 1; }
};
//развертка в действующий стандарт
struct derived : base {
static constexpr int get_attribute__inner() { return 1; };
virtual int get_attribute() override { return get_attribute__inner(/*форвард аргументов*/); }
};
Александр
Constantine
можно макросами обмазать
🐙 Antony
предлагаю вместо virtual использовать override
Constantine
т.е. начинать декларацию с override?
🐙 Antony
Не, фигня получается
struct base {
override static constexpr int get_attribute();
};
usernameak
Крылатый
override уже ведь занят.
Constantine
в данном случае речь идет о наложении дополнительных требований на тело функции
Constantine
весьма непонятен вопрос сигнатуры такой функции
usernameak
virtual в таком случае должен резолвиться на этапе компиляции
Constantine
он не может быть зарезолван
Крылатый
constvirual
Крылатый
Вводим новое
Constantine
struct base {
virtual int get_attribute() constexpr = 0;
};
struct derived : base {
virtual int get_attribute() constexpr override { return 1; }
};
void foo(base const& b) {
b.get_attribute(); //значение?
//base::get_attibute(); //ошибка компиляции
derived::get_attibute(); //все-таки должно быть нормально
}
Диджитал
реальное применение можешь озвучить?
Constantine
сериализация объектов с фабрикой по имени
Constantine
фабрика по имени создает объект конкретного типа и безумно хочет, чтобы любой созданный ей объект в ответ на запрос имени возвращал то же самое
Constantine
сейчас фабрика в этом случае может использовать map и RTTI
Constantine
что является ручной реализацией vtbl по сути
Berkus
вряд ли из-за одного маргинального юзкейса это надо тащить прямо в язык
Constantine
почему маргинального?
Berkus
ну потому что это и так уже можно сделать с RTTI
Диджитал
я вижу только один смысл тащить значение в vtbl - избежать лишнего вызова
Constantine
реализация map+RTTI позволяет вообще не использовать виртуальные функции
Диджитал
что нужно только в условиях жестких требований к производительности
Berkus
Constantine
так и не надо
удалить виртуальные функции из языка как сахар?)
Constantine
на самом деле, я уверен, юзкейз можно найти в любой библиотеке с динамическим полиморфизмом
Constantine
Это какой-то софизм. Язык для программ, а не язык - вещь в себе
Nik
Можно пойти дальше и потребовать возможность задавать кастомные атрибуты
Constantine
Я все еще уверен, что в любой реализации есть такие функции
Constantine
И есть контракты на уровне оговорок, которые я предлагаю в язык
Constantine
Просто STL совершенно не использует динамический полиморфизм
Constantine
Да, но это совершенно невозможно в разработке хоть немного сложной программы
Constantine
При этом нет ни одного способа преобразовать контракты статического полиморфизма "задано constexpr поле" в динамический
Constantine
Например, фактическая реализация std::function после потери типа не может потребовать проверить из внутреннего интерфейса по контракту "is_nothrow_move_constructible"
Constantine
Кстати, надо запомнить, годные аргументы для преамбулы
Диджитал
пока что звучит так, что тебе скорее нужны хитрые ассерты, а не правка vtbl
Constantine
это невозможно проверить никаким ASSERT-ом, потому что это статическая проверка
Constantine
на MSC это очень условно можно проверить ассертом, передав 0 в качестве this в конкретную функцию
Constantine
по ISO это UB
Диджитал
я про статический ассерт и говорил
Constantine
статический ассерт в данном случае невозможен в принципе, я не могу проверить тело функции
Диджитал
и нет, я не подразумевал. что это можно сделать существующими средствами, возможно, просто их расширить
Constantine
внедрение интроспекции уровня чтения кода действительно решит эту проблему, но является невозможной задачей
Диджитал
если потребовать определения тела в хедере - то почему невозможной?
Constantine
потому что тело функции иногда оптимизируют
Constantine
функции после компиляции может вообще не существовать
Constantine
забавно, пример действительно есть в реализации std::function в MSC
virtual const _XSTD2 type_info& _Target_type() const _NOEXCEPT = 0;
Constantine
http://en.cppreference.com/w/cpp/utility/functional/function/target_type
Диджитал
так это здесь неважно, важно, чтобы функция имела вид return constexpr
Constantine
и как это проверить через static_assert?
Диджитал
ввести новый тип ассерта
Constantine
и что он должен сделать? вызвать функцию, которая не помечена constexpr?