Ответы пользователя по тегу C++
  • Почему объект не передается по ссылке?

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

    Скорее всего у вас внутри конструктора BoxContainer идет присвоение в член nbox. Но у вас не определен оператор присвоения (или конструктор копирования) для NumberBox. Определите его (можно default). Так что с передачей по ссылке все хорошо, но вот то, что вы дальше с этой ссылкой пытаетесь сделать у вас не работает.

    Руководствуйтесь правилом трех-пяти.
    Ответ написан
    2 комментария
  • Почему не работает выражение в интерпретаторе?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Отладчик есть? Или хотя бы отладочный вывод добавьте. Выводите все переменные там, где они меняются. Мне кажется, что вы из строк все пробелы удаляете и у вас segment получается "sqrt(x);". Ведь stringstream будет читать одно слово целиком до пробельного символа, а их там тупо нет. И потом проверка segment == "sqrt" не срабатывает. Но мне лень ваш код запускать, перепроверьте эту гипотезу сами.

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

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Заведите, например enum со всеми версиями виндоуз и занумеруйте их. Смещения ваши раскладывайте не по неймспейсам, а массиве. Во время исполнения через winapi получайте версию винды и приводите ее к значению в вашем энуме. Его используйте как индекс в массиве.
    Ответ написан
    2 комментария
  • Не могу найти ошибку в коде?

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

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Во-первых, вы уверены, что у вас эти 10-15% - это загрузка ядра, а не вcего процессора? Диспетчер задач обычно показывает как 100% полную загрузку всех ядер.
    Во-вторых, что у вас там за вычесления? Работа с целыми числами? Float? Всякие векторные инструкции? Точно нет никаких пауз вроде sleep()?

    Выделение памяти медленное, да, но это потому что надо много вычислений сделать, чтобы найти какой-же кусок памяти выдать программе.

    Самое вероятное место для тормозов - это вывод на экран/в файл. Если вы много отладочной информации выводите, это будет бутылочным горлышком.

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

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

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

    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.
    Ответ написан
    Комментировать
  • Рандом маленькой разброс, как увеличить в рамках диапазона?

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

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

    В этом главная проблема Undefined Behavior: компилятор его почти всегда не видит, и программа с ним может даже работать в каких-то случаях так, как программист задумывал. А в других совершенно необъяснимо падает или выдает бред.

    У ОС защита от такой наглости с памятью, конечно, есть. Такая программа рано или поздно упадет с access violation, segmentation fault или еще чем-то подобным, когда цикл дойдет до не вашей памяти.
    Ответ написан
    Комментировать
  • С++ автоматически вставляет в функцию ссылку на вектор?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Это называется "передача по ссылке". Гуглите.
    Ответ написан
    Комментировать
  • C++ std::cout не выводит ничего?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Разность в поведении между сборками может быть обусловлена двумя причинами:
    1) в коде есть ifdef и часть функциональности просто отключена в релизной сборке. Довольно часто так намеренно отключают отладочный вывод.
    2) В коде есть ошибка, какое-то undefined behavior и при оптимизации в релизной сборке часть кода вырезается компилятором.

    Какой-то другой причины чтобы cout не работал в релизной сборке я не вижу.

    printf вы наверное сами куда-то добавили. Если заменить в коде библиотеки отсутствующий cout на printf оно так же работает? Или у вас нет доступа к коду?
    Ответ написан
    5 комментариев
  • Откуда появляется это странное число?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Читайте код внимательно:
    Ввод:
    for (int i=0; i<x; i++){

    Вывод:
    for (int i = 0; i <= x; i++){

    У вас там <= в конце. Из-за этого идет обращение к элементу по индексу x, за границей массива. И оттуда выводится какой-то мусор - это и есть ваше странное число.
    Ответ написан
    Комментировать
  • Насколько больше будет занимать памяти Свойство (get + set)?

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

    Если вы сделаете просто методы Get и Set, то будут точно такие же 2 функции в памяти. Важно, что в вашем текущем и в предолженном решении функции не храянятся в эксземплярах объекта. Обычно они в коде программы встречаются ровно по одному разу*.

    *Если не учитывать инлайнинг функций. Иногда компилятор вместо вызова тупо вставлят тело функции в код. Но это не сильно увеличивает размер кода обычно. И никак не зависит от количества и размера объектов в памяти.
    Ответ написан
    Комментировать
  • Как правильно перегрузить шаблонный оператор (метод, функцию), чтобы наследники попадали в нужный?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Можно попробовать enable_if<> скомбинировать с is_base_of<>. Только нужно все ваши классы Id унаследовать от одного какого-то общего. И во всех наследниках объявлять int поле, которое и брать в теле функции. Только уже не получится этот int сделать параметром шаблона.
    Ответ написан
    Комментировать
  • Что значит такое объявления полей в С++?

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

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

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Это еще ничего, а как вы хотите, чтобы парсилась строка "1111,2222,3333"? Как 11112222.3333? Или 111.22223333? Или что?

    Правильный ответ: если строка не является корректно записанным числом, то надо выдавать ошибку, а не пытаться незаметно для пользователя исправить за него ошибки.

    Например, можно просто читать сразу число. Если вам надо, чтобы число было корректным и при использовании '.' и ',', то можно просто все запятые поменять на точку.
    Ответ написан
    2 комментария
  • Vcpkg: почему видит хедеры, но не видит cpp файлы?

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

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Что этот код должен, по вашему делать? Я отлично вижу, как он может в этих случаях вернуть false. Если ваш цикл в вашем UNORDERED мапе сначала возьмет самый последний символ сторки part1, то он присвоит переменной order максимально возможное значение и больше ни одино условие в цикле не выполнется - ни один символ больше не удалится.

    Разница в поведении компиляторов обусловлена тем, что они по разному мешают этот самый НЕУПОРЯДОЧЕННЫЙ мап. Возможно, там разные хеш функции используются.

    И, кстати, ваши multimap-ы тут вообще бесполезны. Во-первых, зачем вам MULTImap, ведь у вас все ключи - это индексы симовлов - уже разные. Во-вторых, зачем вам вообще map, если вы там по каждому индексу храние символ, что итак уже делает строка! У вас там part1map[i] == part1[i] всегда. Вместо цикла по мапу, можно пройтись циклом от 0 до длины строки.
    Ответ написан
    Комментировать
  • Почему тут требуется cast double -> int?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Вообще, преобразование из double в int - это не ошибка. Это warning (и то, он выводится, только если компилятору указать -Wconversion. Код выше этот варнинг выдает во втором месте, но все-равно компилируется.

    Если у вас преобразование умышленное, и вы знаете, что там не будет ошибки переоплнения, то вы можете использовать static_cast тогда компилятор не будет выдавать предупреждение.
    Ответ написан
  • Где Decimal в C++?

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