Пользователь пока ничего не рассказал о себе

Достижения

Все достижения (1)

Наибольший вклад в теги

Все теги (9)

Лучшие ответы пользователя

Все ответы (26)
  • Какие виды функций есть в C++, и как их различать?

    @code_panik
    В c++ есть бинарный оператор <<, который для целых чисел является оператором сдвига битов числа влево на заданное количество позиций (то же, что и повторное умножение на два). Например, программа напечатает 2 << 1 == 4,
    #include <iostream>
    using namespace std;
    
    int main() {
        cout << "2 << 1 == " << (0b010 << 1); // 0b100
        return 0;
    }

    Одна из основных возможностей языка - перегрузка функций, в частности встроенных операторов (не всех). То есть мы можем определить свой тип данных со своей реализацией оператора <<.
    #include <iostream>
    using namespace std;
    
    struct Foo {
        Foo& operator<<(int x) {
            cout << "Integer: " << x << '\n';
            return *this;
        }
    
        Foo& operator<<(const char* str) {
            cout << "String: " << str << '\n';
            return *this;
        }
    };
    
    int main() {
        Foo foo;
        foo << 3; // Integer: 3
        foo.operator<<("Hello world"); // String: Hello world
        return 0;
    }

    Для компилятора запись foo << 3; значит именно вызов функции foo.operator<<(3). Аналогично в случае cout, объекта типа std::ostream, который представляет поток вывода (character output).
    https://en.cppreference.com/w/cpp/io/basic_ostream...
    Ответ написан
    Комментировать
  • Почему НЕ vim? Vim для серьезной разработки?

    @code_panik
    Среды разработки отличаются уровнями абстракций средств, предоставляемых пользователям.

    В самом простом текстовом редакторе нам доступны функции редактирования последовательности символов.

    vim добавляет новые уровни абстракций, например команды и регулярные выражения. Поток символов получает структуру слов, строк, абзацев, содержимого (например в скобках) и т.п.

    Текстовые редакторы в IDE добавляют уровень абстракций языка программирования. Слова становятся именами классов, функций, инструкций языка.

    Голый vim не заменит IDE, а IDE не заменит vim, потому что они существуют на разных уровнях абстракций.
    Можно в vim тащить функции IDE или в IDE тащить vim. Я выбрал второй путь и тащу голый vim с минимальным vimrc почти в каждую IDE. В visual studio, vs code есть vim plugin, в Idea есть свой плагин, наверное лучший из всех. В Qt Creator есть fake vim. При работе со всеми плагинами сталкивался с ограничениями функциональности самого vim, а fake vim был самым проблемным. Но если нет особых требований к работе в vim, этот путь намного проще. Поэтому лучше начинать с него, и только потом, если будет не хватать функций vim, переходить на vim с IDE плагинами.
    Ответ написан
    1 комментарий
  • Как убрать ошибки взаимодействия между классами?

    @code_panik
    Если структуру классов не нужно менять, то можно сделать как в рабочем примере.
    Перед Window_mgr достаточно объявить (forward declare) class Screen. Просто нужно иметь ввиду, что в файле класса Window_mgr это неполный тип (incomplete type).
    И во friend объявлении не хватает Window_mgr::ScreenIndex.
    Ответ написан
    1 комментарий
  • Как превратить void() в void (**)()?

    @code_panik
    UPD: Похоже, проблема в библиотеке
    https://github.com/espressif/arduino-esp32/issues/7675
    Исправляющий комит
    https://github.com/espressif/arduino-esp32/commit/...

    Довольно странное требование для api.
    Если вы пишите класс-обертку над этой функцией, то она принимает просто функцию, а не указатель на указатель.
    В C++ функция определяется своим адресом, и правила передачи функции в функцию похожи на правила передачи обычного массива.
    Похоже, проблема именно в объявлении вашего register_callback, которое можно реализовать как в этом примере
    #include <iostream>
    using namespace std;
    
    using esp_spp_cb_event_t = int;
    using esp_spp_cb_param_t = void;
    
    void btCallback(esp_spp_cb_event_t event, esp_spp_cb_param_t *param) {
        cout << "btCallback" << endl;
    }
    
    class MyBt {        
    public:
        typedef void (*callback_type)(esp_spp_cb_event_t, esp_spp_cb_param_t *);    
    
        void register_callback(callback_type cb) {
            cb(0, nullptr);
        }
    };
    
    int main()
    {    
        MyBt bt;
        bt.register_callback(btCallback);
        return 0;
    }
    Ответ написан
    5 комментариев
  • Каковы правила конвертации указателя на массив неопределенной длины в указатель на массив определенной длины?

    @code_panik
    В выражении p = p2 мы выполняем неявное преобразование встроенных типов, для которых в стандарте не описаны правила преобразования. То есть такое преобразование не гарантировано, но может быть реализовано компилятором, например
    #include <type_traits>
    using namespace std;
    
    int main() {
        static_assert(std::is_convertible<int(*)[2], int(*)[]>::value, "Non-convertible");
        return 0;
    }

    компилируется в gcc 12.2, в clang 15.0 - ошибка.

    Существует старое не принятое предложение о закреплении такого преобразования стандартом.
    Ответ написан
    1 комментарий