Задать вопрос
  • Почему без std::remove_reference_t не работает?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Вообще, не вижу противоречия. У вас же там tfunc&&, его вы пытаетесь к void* привести и к нему применяете remove reference.

    Попробуйте в ваш static assert добавить std::move и он обвалится.
    Ответ написан
    Комментировать
  • Можно ли написать template deduction guide только для второго аргумента?

    @Mercury13
    Программист на «си с крестами» и не только
    Пока получилось через функцию.

    #include <utility>
    #include <iostream>
    
    class Cursor {
    public:
        Cursor(int aShape) noexcept : fShape(aShape) {}
        int shape() const noexcept { return fShape; }
    private:
        int fShape;
    };
    
    template <typename T, typename TFactory>
    class Lazy {
    public:
        Lazy(TFactory&& x) : factory(std::move(x)) {}
        Lazy(const TFactory& x) : factory(x) {}
        T operator()() const { return factory(); }
    private:
        mutable TFactory factory;
    };
    
    template <typename T, typename TFactory>
    inline auto lazy(TFactory&& factory)
    {
        return Lazy<T, std::decay_t<TFactory>>(std::forward<TFactory>(factory));
    }
    
    int main()
    {
        auto arrow = lazy<Cursor>([] { return Cursor(42); } );
        std::cout << arrow().shape() << '\n';
        return 0;
    }


    Может, шаблонного полиморфизма вам хватит, но я бы довольно быстро прикрутил виртуальный полиморфизм.
    Ответ написан
    Комментировать
  • Почему в c++ еще нету Null-Conditional Operator?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Это не достаточно частая операция в С++, чтобы срочно надо было вводить новый оператор в синтаксис. Комитет занят более интересными вещами на годы вперед.
    Ответ написан
    3 комментария
  • Почему в c++ еще нету Null-Conditional Operator?

    @Furax
    Используйте метод and_then, он как раз для этого.
    Ответ написан
    Комментировать
  • Можно ли не указывать полный путь до ресурса в другом проекте?

    MDiMaI666
    @MDiMaI666
    Талантливый программист
    - Написать свой img2 и тянуть оттуда надо
    - настроить сборку так чтобы он скопировал в запускаемый проект
    -закинуть файлы в ресурсы resx
    Ответ написан
    1 комментарий
  • Почему не запускается WebAssembly PWA страница?

    Fragster
    @Fragster
    помогло? отметь решением!
    Судя по ошибке надо сделать простейшую публикацию на веб сервере а не запускать как файл. Да, придется разогнать IIS, apache или nginx (я на винде использую IIS, ибо проще всего, но кому-то может быть проще apache в составе чего-то типа wampserver).
    Ответ написан
    2 комментария
  • Можно ли сделать концепт для функции у которой return value auto?

    @Acaunt
    template<class T>
    concept is_exist_metod = requires(T t, std::string_view name) {
        t.GetMember(name);
    };
    Ответ написан
    Комментировать
  • Можно ли в шаблоне через requires ограничить не typename?

    @maksam07
    template<size_t Number> 
    requires (Number <= 1000)
    class MyClass { };
    Ответ написан
    Комментировать
  • Почему может не заходить в обработчик таймер [STM32]?

    @AiR_WiZArD
    0) Где код?
    1) Настолько ли важно замеры проводить с помощью АЦП? Может простейший ФВЧ + компаратор + таймер в режиме input capture? Это проще с программной точки зрения, а рассыпуха копейки стоит
    2) Какие параметры АЦП? Какая частота АЦП, время семплирования, используется ли прерывание по окончании, или блокирующая функция в прерывании?
    3) Правильно ли я понял - вызывается обработчик 3 таймера? Если так, то другой вопрос - зачем? TIM3_TRGO может напрямую запускать преобразование
    4) DMA? Да! И ещё раз - да!
    5) Не понял, зачем тут упомянут TIM2 - если он используется для других задач, стоит выключить на время отладки АЦП, что бы не мешал.
    6) "Симуляцию произвожу в proteus" - не надо, отлаживать надо на реальном железе, симуляторы в таком виде не используются, только изредка qemu для юнит тестов
    7) "Это он не может так быстро обработать" - если симулятор не может обрабатывать в реальном времени, она начинает обрабатывать не в реальном времени, но на логику кода это никак не влияет, просто занимает больше времени.
    8) 8МГц это мало, если нет гонки за каждым миллиампером (в таком случае F1 выкидывается, ставится L0/L1), лучше выставить максимальную частоту (72МГц)
    Ответ написан
    6 комментариев
  • Возможно ли проверить является ли T std::function?

    @Acaunt
    Если правильно понял вопрос, то можно сделать так:
    Пример
    #include <iostream>
    #include <functional>
    
    template<class T>
    struct is_function {
        constexpr static bool value = false;
    };
    
    template<class T>
    struct is_function<std::function<T>> {
        constexpr static bool value = true;
    };
    
    template<class T>
    constexpr static bool is_function_v = is_function<T>::value;
    
    template<class T>
    void check(T t) {
        if constexpr (is_function_v<T>) {
            std::cout << "is std::function" << std::endl;
        }
        else {
            std::cout << "is not std::function" << std::endl;
        }
    }
    
    void f2() {}
    
    int main() {
        std::function f1 = [](){};
        std::function f3 = f2;
        check(f1); // is std::function
        check(f2); // is not std::function
        check(f3); // is std::function
        
        return 0;
    }
    Ответ написан
    Комментировать
  • Можно ли иначе скопировать значение указателя?

    maaGames
    @maaGames
    Погроммирую программы
    Добавь в IProperty чисто-виртуальную функцию Copy. А дальше уже каждый конкретный класс себя будет уметь копировать.
    Ответ написан
    Комментировать
  • Ошибка в вариативном шаблоне. Что не так?

    @Mercury13
    Программист на «си с крестами» и не только
    #include <iostream>
    #include <string>
    
    struct T {
        int x;
        std::string y;
    };
    
    T Deserialize(std::istream& stream, auto T::*... properties)
    {
        T object = {};
        auto FillObject = [&object, &stream] (auto property)
        {
            stream >> object.*property;
        };
    
        (FillObject(properties), ...);
        return object;
    };
    
    int main()
    {
        T r = Deserialize(std::cin, &T::x, &T::y);
        std::cout << "<" << r.x << "> <" << r.y << ">" "\n";
        return 0;
    }

    Что сделано: исправлен вызов FillObject (важно), уточнён тип properties (лучше).
    Ответ написан
    Комментировать
  • Используются ли контекстные меню в играх?

    GavriKos
    @GavriKos Куратор тега Разработка игр
    Да, есть игры с контекстым меню (в цезаре вроде было, в сеттлерсе, ну и наверняка в каких нить ММО легко найдется), есьт разновидность контекстного меню - радиальное меню (невервинтер)
    Ответ написан
    Комментировать
  • Используются ли контекстные меню в играх?

    @Mercury13
    Программист на «си с крестами» и не только
    По правой кнопке не помню, хотя вроде бывают.
    При щелчке показываются иконки вокруг, например, в Incredible Machine. Или во многих квестах. Или в Fallout 1/2.

    Что контекстному меню мешает.

    1. Плохая раскрываемость (discoverability, возможность найти всё это тыком и интуицией). Игры всё-таки должны собирать большую публику необученных пользователей, верно? Я когда-то учил одну даму ходить по Witness (у неё FPS-управление, но никакой реакции не нужно) — так и не смог. Сам прошёл с большим удовольствием, хотя посторонних головоломок нашёл от силы половину.

    Опытный пользователь рабочих программ просто привык — и то, например, в редакторе Unreal Tournament есть одно очень подлое контекстное меню, которое хрен раскроешь (на заголовке каждого из четырёх видов: спереди, сверху, слева, в перспективе).

    В том же Fallout 1/2 есть команда «оттолкнуть» — неписи ходят по своим делам, и если он загородил нужный проход и никуды, приходится на него действовать этой командой. Понятна только через инструкцию.

    2. Нежелание превращать игру в рабочую программу. Чем дальше интерфейс игры от программы, тем лучше иллюзия. Некоторые авторы — сейчас, правда, это сложно, с управлением из шести осей и десяти кнопок — вообще не делают интерфейса. Хоть «↑ = зайти» да и делают даже в играх вроде Braid и Fez.

    3. Если объект подвижный, бывают глюки, когда ты щёлкнул на него, а он ушёл или даже погиб. Если статус-панель опустела, пока мы нажимаем, мы жмём в никуда. Если меню исчезло — жмём куда-то на игровом поле. Подобное больше годится для чего-то неподвижного и прочного.

    4. Теряется правая кнопка мыши. У опытного игрока, который использует всю клавиатуру и даже больше, вдруг отбирают одну кнопку.

    5. Опять-таки раскрываемость — если есть команда, скажем, «патрулировать», не очень понятно, что кнопка P действует, даже если контекстное меню не раскрывать.

    6. Со всей этой раскрываемостью, боковыми панелями и прочим интерфейсом контекстное меню кажется излишним, и годится в двух случаях: или нет статус-панели, или она не отображает наш объект.

    7. А если ещё важно заранее раскрыть и момент улучить — меню мешать будет.

    В общем, контекстное меню может пригодиться, но, во-первых, в интерфейсе, а не на игровом поле. Ну или в медленной игре, где игровое поле мало чем отличается от интерфейса. А во-вторых, оно по определению дублирует команды, а если в игре их немного (иначе хрен этой игре обучишься), ничего не стоит вывалить их все другим методом. А те игры, которые делают доступ ТОЛЬКО через контекстное меню — ну, учитесь у Fallout 1/2 и Incredible Machine.

    UPD. Вспомнил. В Mafia и некоторых частях Hitman, если действий вокруг много, по кнопке «Действие» выводит меню: что выбираешь?
    Ответ написан
    Комментировать
  • Данные в таком случае будут хранится в стеке?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    В наше время можно просто проверить: godbolt.org

    И clang и g++ и при локальном и при глобальном объявлении кладут 1 на стек.
    Правда, clang чуть поумнее и выдает warning:
    warning: temporary whose address is used as value of local variable 'Number' will be destroyed at the end of the full-expression [-Wdangling]


    Нельзя надеяться, что по этому адресу останется лежать 1. В более сложных случаях этот адрес может быть переиспользован под что-то еще. Обращение по такому указателю - UB.
    Ответ написан
    Комментировать
  • Данные в таком случае будут хранится в стеке?

    @Mercury13
    Программист на «си с крестами» и не только
    Не пиши так, пожалуйста.
    Перед нами продление жизни временного объекта.
    Когда ссылка исчезнет — а она исчезнет после точки с запятой — указатель будет смотреть в никуда, и только от Ктулху зависит, когда переменную перезапишут.
    Правильно так:
    const int& ref = 1;
    const int* Number = &ref;

    Данные могут лежать где угодно — теоретически на стеке, но оптимизатор может перекинуть их и в сегмент данных.

    В общем, правило. Продлённый объект живёт, пока живёт та ссылка, что его продлила. Ссылки и указатели, что сделаны уже из этой ссылки, не в счёт: Си++ всё-таки не «мусорный» язык. Временный объект живёт до точки с запятой, за исключением нескольких случаев: явная команда придержать объект (о которой у нас и речь), создание/копирование массива (для простоты компиляции и чтобы не раздувать стек), с Си++23 в команде «цикл по объекту» ради безопасности и предсказуемости.
    Ответ написан
    Комментировать
  • Куда поместить рендер? Где он обычно расположен?

    GavriKos
    @GavriKos Куратор тега Разработка игр
    Как рендер реализован например в игровых движках

    Используется одно окно, которое сразу фуллскрин.
    Ни разу не видел игр с несколькими окнами.

    1) Принимать рендер в конструкторе.
    Только одна проблема надо для каждого объекта передавать этот рендер. Что не хочется и выглядит как то не очень.

    Нормально выглядит. DI через конструктор.
    Ответ написан
    1 комментарий
  • Нормально ли создавать пустую вирутуальную функцию?

    @Mercury13
    Программист на «си с крестами» и не только
    ВСЕ ПРИМЕРЫ ЖИВЫЕ, у меня перед глазами.
    • stream.flush — физический сброс данных на устройство (при выводе) или сброс буферов (при вводе) имеет место только с реальным устройством, а написанные прикладным прогером потоки редко с ними работают, потому пустая.
    • Импортёр из системы управления предприятием, который для каждого, например, рецепта производства вызывает callback. Если рецепты не поддерживаются — ничего не делать.
    • В каком-то виджете Qt напрочь убираем реакцию на колесо мыши.
    • Программа использует для ускорения кучу кэшей, которые перед импортом данных выкидываются. Если выкидывать нечего — функция compactMemory пуста.
    • Или твоя фигура-квадрат, для которой поворот ничего не делает.
    Ответ написан
    Комментировать
  • Почему нельзя использовать private метод в качестве аргумента для алгоритмов в другом private методе?

    @code_panik
    В комментарии Wataru уже указал на вероятную проблему. Метод класса первым аргументом принимает указатель this на объект класса, который этот метод вызывает. То есть вызов objectName.foo(100) компилируется в нечто такое foo(&objectName, 100).
    Только вместо std::bind проще использовать лямбду. Если в списке захвата лямбды указать this или =, то всеми видимыми методами класса в лямбде можно пользоваться как обычно, https://godbolt.org/z/e9z76vTY7.
    #include <array>
    #include <algorithm>
    #include <functional>
    #include <iostream>
    
    class Container {
    public:
        bool isZeroLambda() {
            return std::ranges::all_of(std::begin(ar), std::end(ar),
                    [this](auto x) { return isZeroValue(x); });
        }
    
        bool isZeroBind() {
            auto pred = std::bind(&Container::isZeroValue, this, std::placeholders::_1);
            return std::ranges::all_of(std::begin(ar), std::end(ar), pred);
        }
    
    private:
        bool isZeroValue(int x) { return x == 0; }
        std::array<int, 3> ar{};
    };
    
    int main() {
        Container c;
        std::cout << c.isZeroLambda()
            << '\n' << c.isZeroBind();
        return 0;
    }
    Ответ написан
    Комментировать
  • Баг цикла или как это объяснить?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Подсказка: вот то число, что у вас в конце выводится - это 2^64-1. Еще подсказка: size_t на современных платформах имеет размер 64 бита.

    У вас переполнение. Вы там из 0 вычитаете 1 в итерации цикла, получаете самое большое число, представимое в 64-битном типе.

    Надо переписать цикл на while и делать из него break по достижению 0. Или тип переменной сменить на знаковый.
    Ответ написан
    Комментировать