170 похожих чатов

Народ, а рефлексия которую планируют добавить в С++26 заменит наконец

лупхолы или нет? Можно ли будет узнать с какими типами проинстанциировалась функция/метод? Это очень нужно для стирания типа - то есть шаблонная функция в одном месте стирает тип а потом мы хотим в отдельном месте пройтись по этим типам с которым была проинстанциирована эта функция чтобы сделать проверку на рантайм-айдишник у объекта таким образом получив статический тип в лямбда-коллбеке
Например вот есть такая обертка ErasedType которая стирает тип
struct A {
....
}
struct B {
...
}
struct ErasedType {
void* ptr;
int typeId
ErasedType(auto obj){
ptr = obj;
typeId = GetUniqueIdForType<decltype(obj>()
}
}
и используем ее когда хотим например вернуть объекты разного типа из функции или добавить в какой-то контейнер
ErasedType getObj(){
if(rand() % 2){
return new A{};
} else {
return new B{};
}
}
но дальше в другом месте программы нам нужно получить статический тип и тут нужен способ пройтись по типам с которыми был проинстанциирован шаблонный конструктор ErasedType чтобы заматчить рантайм-тип (по сохраненному айдишнику) и в случае совпадания вызывать лямбду
auto getStaticType(ErasedType obj, auto fn){
//здесь нужен список типов T1, T2, T3, ... с которым был проинстанциирован конструктор ErasedType чтобы дальше заматичить айдишник и вызывать лямбду с конкретным типом после каста

if(GetUniqueIdForType<T1>() == obj.id){
fn(static_cast<T1>(obj.ptr);
}
if(GetUniqueIdForType<T2>() == obj.id){
fn(static_cast<T2>(obj.ptr);
}
if(GetUniqueIdForType<T3>() == obj.id){
fn(static_cast<T3>(obj.ptr);
}
...
}

ErasedType obj = getObj();

getStaticType(obj, [](auto concreteObj){
//здесь получаем уже статический тип
})

22 ответов

107 просмотров

Да, можно будет делать всё что угодно! P.S.: А чем std::variant не подошёл для это примера?

Интересно, как a.cpp узнает про инстанцирования из b.cpp

Богдан- Автор вопроса
🐙 Antony Polukhin
Да, можно будет делать всё что угодно! P.S.: А че...

с std::variant нужно заранее знать типы, а как я заранее узнаю тип для лямбды? что если я возвращаю по рантайм-if-у из функции или добавляю в контейнер разные лямбды (с разными замыкаемыми переменными) ?

Богдан- Автор вопроса
🐙 Antony Polukhin
Вроде std::function поможет с лямбдами

а как в std::function засунуть шаблонную лямбду?

ИМХО без динамических аллокаций красивее получается: std::variant<A, B> getObj(){ if(rand() % 2){ return A{}; } else { return B{}; } }

Богдан
а как в std::function засунуть шаблонную лямбду?

А как именно выглядит решаемая вами задача? Интересно как вы потом type_erased лямбду в другой единице трансляции в правильгый тип кастите

Богдан- Автор вопроса
🐙 Antony Polukhin
А как именно выглядит решаемая вами задача? Интере...

ну логично что сейчас лупхолы ограничены одной единицей трансляции но через лупхолы пример выше решается так https://godbolt.org/z/7hWfx18qd

Богдан- Автор вопроса
🐙 Antony Polukhin
ИМХО без динамических аллокаций красивее получаетс...

Суть не в динамических аллокациях, суть в том что с std::variant нужно заранее знать типы а пример с лупхолами этого не требует

Богдан
ну логично что сейчас лупхолы ограничены одной еди...

а рефлексия каким образом должна помочь протянуть тентакли за пределы единицы трансляции?

Богдан- Автор вопроса
Богдан
а как в std::function засунуть шаблонную лямбду?

в общем я правильно понимаю что сейчас в С++ нет никаких способов реализовать аналог std::function для шаблонных лямбд, кроме костыльных лупхолов?

Богдан
ну логично что сейчас лупхолы ограничены одной еди...

Красота... А если к std::any добавить функцию visit, ваши цели это покроет?

Богдан- Автор вопроса
Андрей Руссков
а это вообще реально?

Наверняка... Надо только придумать как :)

Богдан- Автор вопроса
Богдан
ну логично что сейчас лупхолы ограничены одной еди...

В общем народ, я тут профиксил один баг и немного отрефактрил и вот мой контрибушн сообществу - https://github.com/vampyrofangclub/horrifiction - маленькая библиотека которая предоставляет два хелпера для реализации своих type-erasure any-like оберток template <typename T> constexpr int __get_id_from_type(); constexpr bool __get_type_from_id_impl(int typeId, void* ptr, auto fn); первая функция по переданному типу возвращает уникальный int-айдишник для типа, например __get_id_from_type<int>() //0 __get_id_from_type<double>() //1 struct SomeStruct {...} __get_id_from_type<SomeStruct>() //2 auto someLambda = [](auto anotherLambda){ return anotherLambda(123); } __get_id_from_type<decltype(someLambda)>() //3 а вторая функция делает наоборот - мы передаем int-айдишник типа (полученный из первой функции) и void* указатель и также шаблонную лямбда-коллбек и функция вызовет этот лямбда-коллбек и передаст этот void*-указатель закастованный в соотвествующий тип (и возвращает bool-флаг прошел ли матчинг - например false если матчинг не прошел и лямбда-коллбек не был вызван) void* myObjPtr = myObj; int myObjTypeId = __get_id_from_type<decltype(myObj)>(); __get_type_from_id(myObjTypeId, myObjPtr, [](auto myObj){ std::cout << "myObj->value:" << myObj->value << "\n"; }); другие примеры (простой Any-враппер для сохранения в контейнере объектов разных типов а также для возврата из функции разных шаблонных лямбд) можно посмотреть тут - https://godbolt.org/z/6GfqE3bes

Богдан- Автор вопроса

почему?

Богдан
почему?

https://en.cppreference.com/w/c/language/identifier#:~:text=All%20identifiers%20that%20begin%20with%20an%20underscore%20followed%20by%20a%20capital%20letter%20or%20by%20another%20underscore

Богдан- Автор вопроса

Похожие вопросы

Обсуждают сегодня

а через ESC-код ?
Alexey Kulakov
29
30500 за редактор? )
Владимир
47
Чёт не понял, я ж правильной функцией воспользовался чтобы вывести отладочную информацию? но что-то она не ловится
notme
18
У меня есть функция где происходит это: write_bit(buffer, 1); write_bit(buffer, 0); write_bit(buffer, 1); write_bit(buffer, 1); write_bit(buffer, 1); w...
~
13
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
program test; {$mode delphi} procedure proc(v: int32); overload; begin end; procedure proc(v: int64); overload; begin end; var x: uint64; begin proc(x); end. Уж не знаю...
notme
6
Как передать управляющий символ в открытую через CreateProcess консоль? Собсна, есть процедура: procedure TRedirectThread.WriteData(Data: OEMString); var Written: Cardinal;...
Serjone
6
Вот еще странный косяк, подскажите как бороться. Я git clone сделал себе всего embassy и примеры там запускаю. Всё хорошо. Но вот решил в cargo.toml зависимости не как в приме...
Lukutin R2AJP
1
вы делали что-то подобное и как? может есть либы готовые? увидел картинку нокода, где всё линиями соединено и стало интересно попробовать то же в ddl на lua сделать. решил с ч...
Victor
8
Ребят в СИ можно реализовать ООП?
Николай
33
Карта сайта