Задать вопрос
Ответы пользователя по тегу C++
  • Можно так сделать с interface?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    По уму, вам надо продумать ваш интерфейс. И тогда подобных извращений не понадобится. Дабавьте туда какой-нибудь способ для итерации по структуре данных для вывода. Или вообще сделайте метод ToString, который бы возвращал строковое представление внутренней структуры для вывода. Это все, естественно, виртуальные публичные методы, переопределенные в двух реализациях.

    То же и со вводом. Если надо как-то во внутренности очереди залезать и обычными push это не сделать, то, например, передавайте в метод CreateFromData() вектор введенных пользователем значений.
    Ответ написан
    Комментировать
  • Как сделать какую-нибудь многозадачность на ардуино?

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

    Можно перед циклом один раз померять - решить, а надо ли вообще мотор включать. Внутри, чтоб электричество зря не жечь, можно даже между вычислениями расстояния сколько-то спать. Смотрите там из расстояния - если оно сильно больше 35 - спите подольше.
    Ответ написан
    2 комментария
  • Почему автодополнение не предлагает мне поля структуры?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Вы хотите вернуть T. У Node - это член Data. Вот и возвращайте _node->data, или какой там у вас смысл у _node. Пока странно, вы наследуетесь от Array, но никак его не используете. По идее надо возвращать первый элемент в массиве.

    Да, еще, по английски правильно capaCity, а не capaSity.
    Ответ написан
  • Импликация (следование) в C++?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Нету в C++ отдельных операторов для этих логических функций. Потому что их все можно составить из И, ИЛИ и НЕ.

    Так, импликация - это !a || b. Эквивалентность - можно просто сравнить 2 переменные: a == b.
    Ответ написан
    1 комментарий
  • Как можно перебирать слова в C++?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Раз у вас во вводе коды каждого символа разделены пробелами, то все просто. Заведите в программе map<wstring, wchar> и где-то в начале напишите 33 строчки вида:
    dict[L"•−"] = L'А';

    Потом входную строку разбейте на части по проблелам. Руками, циклом. Указатель-индекс будет указывать на первый необработанный символ. Найдите первый пробел или конец строки начиная с этой позиции. Кусок между двумя позициями - это текущий код. Его с помощью map'а выше переводите в символ. Сдвигайте индекс первого необработанного символа на позицию после пробела. Ну и аккуратно смотрите, если первый необработанный - пробел, то это пробел между словами - его как есть и выводите, сдвигая индекс необработанного символа на 1.
    Ответ написан
  • Почему не вызывается конструктор копирования при инициализации переменной другим объектом?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Тут сработало copy elision.

    operator& не создает никакого временного Query, а работает сразу с Query в месте его вызова. Поэтому конструктор в пункте 8 создает уже результат.
    Ответ написан
    Комментировать
  • Что делать с этой проблемой?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Исходник в кодировке utf. 'А' действительно занимает 2 байта. Что видит компилятор? Видит 2 байта между кавычками и ругается.

    setlocale() - эта функция во время исполнения программы настроит, в какой кодировке у вас будет просиходить ввод/вывод с консоли. На кодировку исходника оно никак не влияет.

    Тут 2 варианта решения: Или поменяйте кодировку исходника и настройки локали, чтобы 'А' занимало один байт, или работайте с wstring.

    Чтобы не путаться с кодировками, напишите программу, которая выводит численное значение байт прочитанной строки. Запустите ее, введите туда 'А', смотрите, что оно выводит. Поэксперементируйте с разными настройками setlocale(). Если выводит 2 байта - вот эти два байта надо писать в case и использовать wstring. Если выводит один байт, вот его в case и вставляйте.
    Ответ написан
  • Почему выдает ошибку при наследовании?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Для решения этой проблемы по уму надо написать вот это в определении производного класса:
    using Array<T>::_size;
    using Array<T>::_capasity;
    using Array<T>::_data;


    Ответ на вопрос "почему" в С++ всегда один: "потому что стандарт":
    Non-dependent names are looked up and bound at the point of template definition. This binding holds even if at the point of template instantiation there is a better match:


    Проблема в том, что Array зависит от T, а вот его член _size от T не зависит. Ну вот не ищет компилятор независимые имена в зависимых местах. Независимые имена разрешаются в месте определения шаблона, когда еще неясно даже, с каким оно типом будет работать-то. Поэтому он никак до Array достучатся не может, ведь никакого T конкретного у него еще нет.

    Надо как-то компилятору указать, где искать вот эти ваши _size и т.д.
    Например, через this-> или через using или через Array<T>::.

    Вообще от этих правил lookup-а в C++ волосы дыбом встают и куча приколов вылезает. Их надо только запомнить. Оно неинтуитивно, но таково оно есть.
    Ответ написан
    Комментировать
  • Почему внутри шаблона можно иметь доступ к приватному члену внутреннего класса?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    С чего вы взяли, что внутри шаблона это работет? Вы его инстанциировать пробовали (объявить переменную класса Outer<int>, например)?

    Вылезает точно такая же ошибка.

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

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Эффективность поиска заключается в количестве срав-
    нений, произведенных определённым методом.


    Ну так подсчитайте количество сравнений. Напишите эти два поиска, заведите счетчики. Во всех местах, где у вас сравнение элементов происходит, увеличивайте счетчик. Выведите их в конце.
    Ответ написан
    Комментировать
  • Почему типы из заголовка cstdint доступны без его включения?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Вам повезло. Какой-то из включаемых вами других хедеров уже включает cstdint. Поскольку система инклудов в C++ идет еще из C и это дикое и неудобное легаси (текст хедера тупо вставляется в файл вместо include препроцессором), то такое рекурсивное включение работает.

    Но это плохая практика - стоит включать все, что вы используете всегда. Потому что потом вы что-то поменяете, исключив какой-то уже не нужный вам хедер отсюда, или из другого хедера, и у вас вылезет ошибка о неопределенных типах из cstdint.
    Ответ написан
    Комментировать
  • Какую роль играют float и double в скобках?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Такая запись имени типа в скобках в выражении - это явное приведение типа. Тут вы указываете компилятору, что выражение надо преобразовать вот к такому вот типу (флоат, в данном случае).

    float нужен вам в начале, потому что вещественные константы имеют тип double. Поэтому у eps/2.0 и 1.0 в первом цикле имеют тип double, все вычесляется в double. Преобразовав одно из выражений в float вы получаете то, что вам надо. Без этого все вычисления идут в double и ответ находится не тот. На самом деле там float при сравнении все-равно расширяется до double но на результат сравнения это не влияет в данном случае.

    Еще, вместо явного приведения типов, можно поставить f после вещественных констант, чтобы указать компилятору, что это float:
    while (1 + eps/2.0f != 1.0f){

    Тогда вычисления будут во float и ответ будет правильный.

    Во втором цикле double вам не нужен. Ведь вычисления итак идут в этом типе. Да и написано у вас там с опечаткой, вы к типу double приводите все выражение со сравнением. т.е. вы булево значение преобразуете в дабл. Потом оно назад в булево преобразуется при проверке условия циклом. В итоге это бесполезное действие.
    Ответ написан
    Комментировать
  • Крестики-нолики.Проблемы с ходом Х?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    У вас там бесконечный цикл, который читает ход Х. Без единого break внутри - поэтому нет даже теоретической возможности, что вы из него выйдите.

    Упростите код: эти 9 if else условий заменяются на такой код:
    if (us.length() != 2) {
      cout << "?????" << endl;
      continue;
    }
    int row = us[0]-'A';
    int col = us[1]-'0';
    if (row < 0 || row > 2 || col < 0 || col > 2) {
      cout << "????" << endl;
      continue;
    }
    if (pole[row][col] != '_') {
      cout  << "занято" << endl;
      continue;
    }
    pole[row][col] = 'X';
    break;
    Ответ написан
    Комментировать
  • Может ли прерывание прервать выполнение конструктора / деструктора в С++?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Да, может. Но обычно в самих конструкторах о многопоточном доступе не беспокоятся, потому что пока конструктор выполняется - объекта еще нет и никакой конкурентный доступ к нему невозможен. Если конструктор обращается к каким-то другим ресурсам, то вот те ресурсы должны защищаться от многопоточных проблем как обычно - не важно из конструктора к ним обращаются или из какого-то другого метода какого-то класса.
    Ответ написан
    Комментировать
  • Как запретить std:: vector перемещаться?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Можно через vector::reserve задать ему необходимый объем. Тогда он сразу же выделит все память и, если вы не будете в него класть больше этого размера элементы, он не будет перевыделять память вообще.

    Еще можно изменить ваш дизайн. Например, вместо vector использовать list, итераторы в котором не портятся от добавления. Или хранить вместо итераторов/указателей на элементы в векторе индексы.
    Ответ написан
    Комментировать
  • Можно в c++ ли работать с памятью через stream?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Класс std::stringstream как раз это и реализует.
    #include <stringstream>
    
    std::stringstream sout;
    sout << "some string " << 42;
    cout << sout.str();


    Но для сериализации эффективнее будет руками записывать данные в буфер через memcopy: все члены структуры по отдельности чтобы не было проблем с выравниванием. Для строк переменной длины надо будет писать еще и их размер отдельно. Для чисел надо аккуратно с порядком байт разобраться и писать их побайтово.
    Ответ написан
    Комментировать
  • Почему часто можно встретить отступление от структурного подхода?

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

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Разбейте задачу на подзадачи:

    1) Проверить, что данный элемент надо удалить
    1.1) Проверить, что элемент не уникальный
    1.2) Проверить, что элемент - не первый среди одинаковых (один-то его надо оставить)
    2) Удалить элемент из массива дописав 0 в конце.

    Все эти пункты выполняются циклом. в первых пунктах будет удобно завести булевую переменную, которая после цикла будет содержать значение проверки.
    Ответ написан
    Комментировать
  • Почему T * может работать ощутимо быстрее (~ на 25-30%) в качестве хранилища данных, чем std::byte *?

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

    Создайте 2 функции, которые отличаются только вот в этих вот местах.
    Вставьте код в https://godbolt.org/

    Смотрите ассемблерный код для двух функций.

    Может, срабатывает strict aliasing. Видя тип T сомпилятор понимает, что эта переменная не может быть изменена какими-то другими std::byte в соседнем коде и может, например, пропустить загрузку-выгрузку данных в регистр из памяти.

    Может вообще что-то другое.

    Единственный вариант разобраться - это смотреть на ассемблерный код функций, которые вы и сравниваете. Не каких-то кусков, оттуда надерганных, а функций целиком.
    Ответ написан
    Комментировать
  • Ошибка Unhandled exception at 0x0099B514 in ConsoleApplication15.exe: 0xC0000094: Integer division by zero. Как исправить это?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Не делить на ноль.

    Засуньте ошибку в переводчик, если по английски не понимаете. Ну не умеют компьютеры нарушать законы математики - еще в школе же учат, что на ноль делить нельзя.

    Очевидно, что size/3 оказывается 0, потому что size меньше 3.

    Надо менять логику. Или отдельно обрабатывать случай size = 0,1,2 или не делить на 3. Вообще, неясно, откуда в этом коде 3 вылезло и что оно означает.
    Ответ написан
    Комментировать