Здесь не совсем понял что надо сделать.
Может парсер typescript? Тогда почему такие же С++ классы уже есть в файлах?
Зачем что-то с чем-то связывать внутри биндингами?
Есть уже заготовленный регистратор объектов.
Была идея:
1. Парсить *.ts файл с описанием классов
2. Разбивать на токены(ни разу не делал. Что это даёт? Разные сущности?)
3. Получать что-то
4. Это что-то зачем-то связывать с уже готовыми такими же С++ классами.
5. Вывести в стиле рефлексии
А как вы считаете, что хотят и как этого добиться?
Нормально. Если за час не смогли загуглить решения к тем, что не помнят назубок, — вполне годится в качестве проверки.
Непонятно, правда, что именно проверяется. Если б вопрос стоял как "в каком случае лучше использовать const/.../..., для решения каких проблем придуман volatile, и решает ли он эти проблемы" — оно как-то логичнее было бы, что ли.
Получается есть набор С++ классов под стать классам из *.ts файла.
На входе *.ts файл может менять. В нём могут быть данные классы в разной последовательности.
Суть программы — получая такой *.ts файл выводить такой же.
Сделать это через связывание уже готовых С++ классов.
Гарантируется что в *.ts файле могут быть только классы, которые уже подготовлены в С++ исполнение.
Алгоритм программы вкратце:
Комбинация ts классов -> выставление соответствия из уже готовых С++ файлов -> вывод.
В репе есть пример как это делать вручную.
А как автоматизировать?
Наверное:
1. Считать входной *.ts файл.
2. Выцепить названия классов
3. Поместить их в контейнер
4. Пройтись по контейнеру
5. получая очередное имя создавать биндинг, в котором еще в зависимости от имени проставляется тип:
Binder<MarketPolicy> binder("MarketPolicy");
Таким образом получим контейнер биндеров. Что с ними делать?
6. Поместить в некий ObjectRegistry
7. Вызвать метод render()
Не всё понятно. Не понятна наводка что за проставление свойств у такого биндинга, если вдруг у класса есть поля:
Здравствуйте, Максим, Вы писали:
М>Это в теории, а на практике может быть UB при переполнении для знаковых целых. Пример
Переполнение знаковых целых это UB? Я-то думал, что на практике все целочисленные вычисления, хоть с переполнением, хоть без, выполняются по модулю 2^32 или 2^64.
https://en.cppreference.com/w/cpp/language/ub
undefined behavior — there are no restrictions on the behavior of the program. Examples of undefined behavior are data races, memory accesses outside of array bounds, signed integer overflow, null pointer dereference, more than one modifications of the same scalar in an expression without any intermediate sequence point (until C++11)that are unsequenced (since C++11), access to an object through a pointer of a different type, etc. Compilers are not required to diagnose undefined behavior (although many simple situations are diagnosed), and the compiled program is not required to do anything meaningful.
В общем, всё свелось к тому, что надо вывести тип в шаблонном методе и записать его строкой исходя из такой странной записи передачи поля класса по ссылке &LimitPolicy::price:
К примеру, класс:
struct LimitPolicy {
double price;
std::optional<double> stop;
};
Метод:
template <typename Attribute>
void set(std::string name, Attribute attribute){
// <----- получить std::string от Attribute
};
И вот как передают поле:
set("price", &LimitPolicy::price);
Надо внутри set записать тип переданного поля в строку
Понятно, спасибо. В описание просили только плюсы использовать. Предпочтительно С++17.
Т.е. узнать тип можно только в рантайм?
И что это за ссылка на поле класса? До этого примера такого нигде не встречал.
Base* b = (rand() % 2 == 0) ? new Derived1 : new Derived2;
report(typeid(*b));
конкретный тип принципиально не будет известен без выполнения программы. typeid и нужен для выяснения динамического типа, который неизвестен во время компиляции. Ну и ещё для пары сценариев: для type_index и для отладочной печати из макросов/шаблонов (самое полезное!).
И главное: typeid для этой задачи использовать не надо.
В общем случае он не позволит её решить, а частные случаи будут либо бесполезны с практической точки зрения (например, предварительная регистрация всех возможных комбинаций поддерживаемых type_index), либо очень сложны и непереносимы (вроде запуска name-demangle над typeid(f).name() и анализа результатов).
Эта задача совсем на другое: на написание кода, который умеет доставать из шаблонного аргумента типы, которые он содержит, и который умеет сопоставлять его с другими стандартными шаблонами (вроде std::optional, std::variant), чтобы преобразовать последние в соответствующие typescript-конструкции.
A>И что это за ссылка на поле класса? До этого примера такого нигде не встречал.
Нет тут ссылок. В этом контексте — это взятие адреса. На выходе — обычный pointer to (data) member.
Его тип как раз содержит всё что нужно: и тип поля, и тип класса, в котором это поле находится.
// Требуется реализовать класс индекса, для хранения данных по 3-м вложенным текстовым ключам
//
// index["key1"]["key2"]["key3"] = data;
//
// в последнем уровне индекса содержатся данные объект класса Data
//
// Пример заполнение данных по ключам выглядит так:
//
// Data data1, data2;
// Index idx;
// idx.set("key1").set("key2").set("key3").set(data1);
// idx.set("key1.1").set("key2.1").set("key3.1").set(data2);
//
// Пример доступа к данным по ключам:
//
// data1 = idx.get("key1").get("key2").get("key3").get();
//
// в реализации предусмотреть раcширение глубины индексовclass Data {
};
class Index {
};
int main()
{
Data data1, data2, data3;
Index idx;
// добавление в индекс
//idx.set("key1").set(data1);
idx.set("key1").set("key2").set("key3").set(data1);
idx.set("key1.1").set("key2.1").set("key3.1").set(data2);
idx.set("key1.2").set("key2.2").set("key3.2").set(data3);
// получение данных из индекса
data1 = idx.get("key1").get("key2").get("key3").get();
data2 = idx.get("key1.1").get("key2.1").get("key3.1").get();
data3 = idx.get("key1.2").get("key2.2").get("key3.2").get();
return 0;
}
Здравствуйте, reversecode, Вы писали:
R>не боитесь что компании могут сильно обидится и начать бороться с тем что вы выставляете годами вымученные тестовые задание-вопросы ?
Ну да, это к тому, что:
1) Ок для соискателя, если человеку дали вопросы, он погуглил, нашел эту тему — старается.
2) Ок для компании, что если пару лет были одни и теже вопросы, можно придумать что-то новенькое.
R>а очень разносторонние девелоперы, вообще он хот знание не держат в голове, иначе сума сойдут
Хорошее замечание. Последнее время спрашиваю вопросы и материалы для подготовки. Что интересно — hr'ы говорят. Им дают обратную связь кандидаты или сами компании могут нормально к этому относится и сами советуют. Мне сейчас по postgresql посоветовали по конкурентную запись почитать, индексы и т.п. для следующего этапа.
3 этапа:
1. Создать поле. Расставить бомбы
2. Расставить цифры, которые говорят, сколько бомб вокруг
3. Кликнуть по полю, получить результат:
а) Пустое место. Открываются все пустые рядом и пустые рядом с ними и т.д.
б) Цифра
в) Бомба
Сделал 2 этапа:
int x, y, bombs;
//======================
vector<vector<int>> table;
table.resize(x);
for(auto & col: table)
col.resize(y);
// 9 == bomba
// 0 == emptyfor (int i = 0; i < bombs; ++i) {
int row = srand(time_now()) % x;
int col = srand(time_now()) % y;
if(table[col][row] == 9) {
--i;
continue;
}
table[col][row] = 9;
}
//======================for(int col = 0; col < x; ++col) {
for(int row = 0; row < y; ++row) {
if(table[col][row] == 9)
continue;
/*
col - 1, row
col + 1, row
col , row - 1
col , row + 1
col , row
col - 1, row - 1
col + 1, row - 1
col - 1, row + 1
col + 1, row + 1
*/int bombs_around = 0;
int cols[] = [col - 1, col, col + 1];
int rows[] = [row - 1, row, row + 1];
for(int l = 0; l < 3; ++l) {
for(int k = 0; k < 3; ++k) {
if(cols[l] < 0 || cols[l] > x - 1 || rows[k] < 0 || rows[k] > y - 1)
continue;
if(table[cols[l]][rows[k]] == 9)
bombs_around++;
}
}
table[col][row] = bombs_around;
}
что то не припомню что бы мне что то посоветовали хоть раз перед собеседованием
причем несколько последних раз я сам несколько раз хр спросил, что будут спрашивать, и к чему готовится
проигнорили мой вопрос
вообщем я всегда собеседуюсь не готовясь