Задать вопрос
  • Поле private суперкласса может быть доступно подклассу?

    @Mercury13
    Программист на «си с крестами» и не только
    class C {
      public static class Inner1 {
        private static int x = 0;
      }  
      public static class Inner2 {
        static void foo() {
          ++Inner1.x;
        }
      }
    }
    
    class D extends C.Inner1 {
       static void bar() {
         //++x;  не работает
       }
    }
    Ответ написан
    Комментировать
  • Возможно ли перегрузить с помощью ограничений?

    @Mercury13
    Программист на «си с крестами» и не только
    Через концепции работает отлично. Через enable_if не вижу способа. Через if constexpr вот так.
    #include <iostream>
    #include <concepts>
    
    class A {};
    class AA : public A {
    public:
        static constexpr const char* AData = "AA";
    };
    
    class B {};
    class BB : public B {
    public:
        static constexpr const char* BData = "BB";
    };
    
    // Через концепции
    template <class T>
    concept ASon = std::derived_from<T, A>;
    
    template <class T>
    concept BSon = std::derived_from<T, B>;
    
    template <ASon T>
    void foo(const T&) {
        std::cout << T::AData << std::endl;
    }
    
    template <BSon T>
    void foo(const T&) {
        std::cout << T::BData << std::endl;
    }
    
    template <class T> constexpr bool FALSE_V = false;
    
    // Через if consexpr
    template <class T>
    void bar(const T&) {
        if constexpr (std::is_base_of_v<A, T>) {
            std::cout << T::AData << std::endl;
        } else if constexpr (std::is_base_of_v<B, T>) {
            std::cout << T::BData << std::endl;
        } else {
            static_assert(FALSE_V<T>);
        }
    }
    
    int main()
    {
        foo(AA());
        foo(BB());
        bar(AA());
        bar(BB());
        return 0;
    }
    Ответ написан
  • Как корректно использовать функцию system при компиляции из GCC?

    @Mercury13
    Программист на «си с крестами» и не только
    system("call file.bat");
    Ответ написан
    Комментировать
  • Могут ли возникнуть проблемы при одновременном чтении и записи в разных потоках переменной?

    @Mercury13
    Программист на «си с крестами» и не только
    Сильно зависит от того, что такое size_t, но на распространённых платформах, где size_t совпадает с разрядностью машины, может или расти скачками, или вообще висеть в одном состоянии.
    Ответ написан
    Комментировать
  • Можно ли написать 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;
    }


    Может, шаблонного полиморфизма вам хватит, но я бы довольно быстро прикрутил виртуальный полиморфизм.
    Ответ написан
    Комментировать
  • Как записать все найденные слова в массив?

    @Mercury13
    Программист на «си с крестами» и не только
    У вас тут ожидается результат неопределённого размера.
    Лучше использовать динамический список вроде ArrayList.
    Ответ написан
    3 комментария
  • Почему адаптеры из range функторы?

    @Mercury13
    Программист на «си с крестами» и не только
    Для реализаций из STL — просто чтобы программист не закладывался на то, что он функция (иначе можно сделать код, привязанный к конкретной реализации), а писал шаблон.

    Если же это точка, где вы сами должны что-то дописать — что вам мешает сделать именно функцию? Функтор — это не только функция, а что угодно, что можно вызывать как функцию.
    Ответ написан
    6 комментариев
  • Почему bool оператор возвращает false, хотя на деле условия для true соблюдены?

    @Mercury13
    Программист на «си с крестами» и не только
    Стандартная ошибка наплюсника, аж две штуки.

    МАКРО-УРОВЕНЬ: вы пишете свою строку, но вместо того, чтобы сделать её отдельным объектом, инкапсулируете внутри Overcoat.

    Рисунок кода Си++ в точности обратный — всё, что умеет удерживать-отдавать ресурсы, переносится в отдельный объект небольшого размера. К тому же использование таких вот небольших объектов позволяет идиому «by-value+move»: если параметр — временная our::String, она просто переносится, а если нет — ну йок так йок.

    НЕПОСРЕДСТВЕННАЯ ПРИЧИНА: сравниваете указатели на буфера, а не содержимое строк.
    Ответ написан
    1 комментарий
  • Может ли быть общая точка у стягивающейся системы интервалов?

    @Mercury13
    Программист на «си с крестами» и не только
    Условие, когда имеет общую точку: последовательности a[n] и b[n] нестационарны: для любого a[n] найдётся другое a[N] большее, для b[n] аналогично меньшее.
    НЕОБХОДИМОСТЬ: они имеют общую точку — это значит, что общая точка x = lim a[n] > всех a[n], и меньше всех b[n].
    ДОСТАТОЧНОСТЬ: для каждого (a[n], b[n])⊃[a[N], b[N′]], и дальше теорема о вложенных отрезках.
    Для стационарной последовательности такого не будет — при достаточно большом n как минимум точка a[n] не будет принадлежать интервалу и будет принадлежать отрезку.
    Ответ написан
    Комментировать
  • Как избавится от эффекта бандинга/постеризации градиента?

    @Mercury13
    Программист на «си с крестами» и не только
    1. А точно исходник 16-битный?
    2. А точно преобразование происходит в 16 битах?
    3. А программа-просмотрщик поддерживает deep colour? Или, на худой конец, дизерит эти цвета?
    4. А монитор поддерживает?
    Ответ на любое из этого «нет» — полосы будут! Исключение: если дизерит, значит как-то компенсирует, что монитор всего лишь 8-битный.
    Ответ написан
    Комментировать
  • Как узнать первые признаки, что ноутбук больше не включится?

    @Mercury13
    Программист на «си с крестами» и не только
    Что может деградировать, чтобы потом сломаться окончательно?

    Экран. Если экран на CCFL (ныне сомнительно) — экран начал смещаться в красное. На белых диодах — смещаться в синее, причём пятнами.

    Микронеконтакт. Всё чаще стали происходить блускрины случайного происхождения, артефакты видео, отказы видео в 3D-режиме.

    Диск выработал ресурс. На механическом диске доступ к определённым местам стал слишком долгим. Что там на SSD с подобными признаками, сказать не могу.

    Итак, у вас там отказ чего-то в видяшной подсистеме — скорее всего, видеопамяти или обвязки матрицы. Это значит, что старый ноут уже устал, и надо готовить ему замену. Подозреваю либо микронеконтакт, но поиск таких неконтактов —  та ещё работа. Либо плашку памяти, отказавшую по счастливой случайности на том куске, который изначально при загрузке компьютера прикарманила встроенная видяха.
    Ответ написан
    Комментировать
  • Какая функция (или набор разных ф-ий) изменения "мощности" цвета света при распространении луча?

    @Mercury13
    Программист на «си с крестами» и не только
    Яркость лазера должна меняться с дальностью экспоненциально — яркость = A·e{Bx}: чем больше фотонов, тем больше рассеивается, дифур y’=−ky.
    Не забывайте, что sRGB сам нелинейный и состоит из линейного и степенного участка, но в целом неплохо приближается функцией y^2,2.
    Ответ написан
    Комментировать
  • Как синхронизировать процессы используя только std?

    @Mercury13
    Программист на «си с крестами» и не только
    Для чего нужен межпроцессный мьютекс? Для объекта (обычно куска памяти), который не проверяется на уровне системы и в то же время разделён между процессами.

    А в стандарте Си++ вообще такие объекты есть? Файлы проверяются. Каналы — насколько помню, нет стандартных, но они тоже проверяются.

    UPD3. Syncstream всё же содержит мьютекс, но второе решение — скопить данные в stringstream и сбросить их одной транзакцией — работает.
    Ответ написан
  • Не удаётся продолжить выполнение кода, поскольку система не обнаружила sfml-graphics-d-3.dll. Как исправить ошибку?

    @Mercury13
    Программист на «си с крестами» и не только
    Найти, где система сборки создаёт EXE. И положить рядом нужный DLL.
    Ответ написан
    Комментировать
  • Как правильно указать авторское право на шрифт?

    @Mercury13
    Программист на «си с крестами» и не только
    CC-BY-SA — очень неудачная лицензия для строительных блоков, у которых есть два метода пользования: построение новых блоков и использование по назначению в составной работе. Но если предполагать, что они разрешают менять ШРИФТ и использовать ГДЕ УГОДНО на манер OFL — то как-нибудь, достаточно простого указания где-то в about, титрах или другой сопроводительной документации:

    FONT: Minecraft Ten by Vania 5617sonfan, CC-BY-SA 3.0

    Если шрифт простым файлом, доступным методом «потянись и скопируй» — то лучше приложить текст лицензии в файле вроде LICENSE-MinecraftTen.
    Ответ написан
  • Приведите пример использования readObjectNoData() при десериализации?

    @Mercury13
    Программист на «си с крестами» и не только
    Так просто, одним куском кода, это сделать нельзя. readObjectNoData() работает только на враждебных данных, которые ещё надо ухитриться сфабриковать.

    // Пишет вот такой код
    class A implements Serializable { }
    class B extends A {}


    // А читает вот такой
    class A implements Serializable { }
    class AHalf extends A {
      private void readObjectNoData() throws ObjectStreamException {}
    }
    class B extends AHalf {}


    Если записать объект класса B первым кодом и прочитать вторым, должно сработать.

    Смысл readObjectNoData() — привести объект в подходящее состояние, когда 1) данных по промежуточному классу AHalf нет; 2) у него какие-то нехорошие инварианты, что так просто в свежеинициализированном состоянии он негодный: ну, к примеру, конструктор по умолчанию скрыт и служит только для десериализации, а так он просит объект для своего создания.
    Ответ написан
    Комментировать
  • Какой алгоритм можно применить при проверки числа на простое ли оно?

    @Mercury13
    Программист на «си с крестами» и не только
    Если нужно проверить а) точно, и б) одно; в) не очень большое число (миллион тоже небольшое) — ничего нет лучше, чем проверка нечётных чисел до корня из n. То есть до 1000.

    Если точно, много и небольшие — то придётся держать список простых чисел, пополняя его, когда попадётся слишком большое число. Список тоже до корня из n. Допустим, если предел — int4 (≈4 млрд), то нужно держать только список до 65535, это пара тысяч чисел.

    Если число совсем небольшое и может быть где-то в списке — ищем его хитрой разновидностью поиска: проверяем 1-е число, 2-е, 4-е и т.д., пока не определим диапазон, где может быть число. И в этом диапазоне ищем двоичным поиском.

    В криптографии востребован неточный поиск — «число, скорее всего, простое». Но об этом не будем, вы не настолько круты. Тут уже основано на том, что держим таблицу небольших простых чисел и делим на них, а затем гоняем неточные тесты.

    PERFECT number — это СОВЕРШЕННОЕ число. Это не то (сумма всех делителей равняется самому числу), и для теста на совершенное число тоже надо проверять до корня из n — если a делится на b, то добавляем и b, и a/b (кроме случаев, когда b=1 и b²=a, разумеется). Если есть простые числа до корня из n — тоже можно разбить на простые множители (один из множителей может быть больше корня из n!) и подключить комбинаторику, чтобы заполучить остальные.
    Ответ написан
    2 комментария
  • Можете посоветовать какой-нибудь задачник по патернам проектирования?

    @Mercury13
    Программист на «си с крестами» и не только
    Задачник невозможен, потому что…
    1. Паттерны проявляют себя в крупных программах. Даже 2000 строк можно написать по наитию.
    2. Нет единого ответа. И как вы будете сверяться, верно вы сделали или нет?
    3. Сильно зависит от языка: например, идиома pimpl — это чистый Си++.
    4. Даже зависит от того, библиотека встроенная или внешняя: внешние библиотеки в низкоуровневый код всегда стараются вносить очень осторожно.

    Пример: нам надо включать-выключать лог в консольной программе, простейший вопрос. Варианты…
    1. Просто переменная isLoggingOn, которая включает этот самый лог.
    2. Одиночка-стратегия-null object.

    И тут появляется вопрос: а что делать, если у нас тут ещё и форматирование на манер printf? Где находится утилита форматирования: в «волшебном круге» интерфейса Logger или нет? А если нет — то можно придумать модуль-утилиту за пределами этого «волшебного круга»? А если пишем на Си#, может, этот модуль-утилита — это метод-расширение? А если пишем на Си++, может, вообще можно не заморачиваться из-за того, что связанные с std::format функции шаблонные и если ни одна не расшаблонилась — с нас и взятки гладки?
    Ответ написан
    Комментировать
  • Почему строку можно изменить через массив, но через указатель нельзя?

    @Mercury13
    Программист на «си с крестами» и не только
    Потому что в Си++ — в отличие от Си — строковый литерал "hello" имеет тип const char[]. Как дополнительную подсказку, что даже если система (скажем, DOS) не имеет разделения памяти по типам и позволяет менять такие литералы — Windows имеет и не позволяет.

    РАЗ. У указателя и массива несколько разная семантика
    char hello1[] = "hello";   // массив длины 6, в изменяемом сегменте или стеке,
                             // данные скопированы из литерала, который
                             // сидит в неизменяемом сегменте
    const char* hello2 = "hello";   // указатель направлен прямо на литерал,
                             // и попытка изменить его под Windows — вылет


    ДВА. Компилятор имеет право спрессовать два литерала в один, и смена одного, скорее всего, сменит и другой. Не могу проверить на Windows — говорил же, что запись в строковый литерал под Windows приведёт к вылету — но, скорее всего, так будет. Что-то вроде
    char* hello1 = const_cast<char*>("hello");
    char* hello2 = const_cast<char*>("hello");
    hello1[1] = 'U';   // hello2 = "hUllo" в системах вроде DOS, где не вылетит
    Ответ написан
    4 комментария
  • Стоит ли использовать блоки кода для ограничения области видимости?

    @Mercury13
    Программист на «си с крестами» и не только
    Иногда, чтобы прикрыть теоретическую возможность важной ошибки.
    Чаще нужно в Си++ с его автодеструкторами.
    На чтение особо не влияет.

    Вот пример на Си…
    { char* buf = calloc(n, sizeof(char));  // Ради чего я создал блок — ставлю в той же строке
        snprintf(buf, n, some_shit);
        strcpy(dest, buf);
        free(buf);
    }


    Ну а это чистые «кресты».
    { std::ofstream os(fname);
       os << someData;
    }  // Тут файл закрыт
    Ответ написан
    Комментировать