Ответы пользователя по тегу C++
  • Что означает *&?

    Nipheris
    @Nipheris Куратор тега C++
    делает тоже самое что и передача простого int по ссылке в функцию?

    Скорее всего вы не очень удачно выразились, поэтому попробую догадаться: да, передача ссылки на int, ссылки на float, ссылки на int* и ссылки на float** ничем принципиально не отличается. В обоих случаях вы получаете идентификатор, в кторый можно присваивать значение того типа, на которое у вас ссылка (т.е. int, float, указатель на int, указатель на указатель на float), и это значение попадёт в ту область памяти, которая была "завёрнута" в ссылку при вызове функции. Это может быть как обычная переменная, так и какой-нибудь разыменованный указатель.
    Ответ написан
    Комментировать
  • Какие библиотеки грамотно составлены, с чего брать пример?

    Nipheris
    @Nipheris Куратор тега C++
    header-only: nlohmann_json
    компилируемая: fmt, zeromq, libuv

    Стоит предупредить, что даже в приличных библиотеках в CMake-скриптах и в целом в инфраструктуре сборки может встречаться жуткая дичь (где-то - из-за необходимости поддержки старых версий CMake, где-то - из-за того что никому нет дела, пока оно работает), поэтому если собираетесь использовать эту сборочную систему, сразу читаем сюда: https://cliutils.gitlab.io/modern-cmake/ . Вот есть неплохой пример структуры проекта.
    Ответ написан
    1 комментарий
  • Что значит typename?

    Nipheris
    @Nipheris Куратор тега C++
    1. typename в данном случае нужен компилятору только как подсказка от разработчика, что последующий идентификатор (т.е. std::stack<T>::container_type::iterator) - это действительно имя типа. Подсказка нужна потому, что этот typedef вероятно находится также в шаблоне, и мы ещё не знаем, во что конкретно инстанциируется шаблон std::stack (в этом случае говорят, что container_type "is dependent on a template-parameter" - пока не инстанциируем std::stack, не узнаем).

    2. Member-тип container_type эквивалентен типу нижележащего контейнера (т.к. std::stack - это адаптер под интерфейс стека, а не реальный контейнер, реальный контейнер для хранения вы выбираете вторым параметром шаблона, по-умолчанию это std::deque).

    3. Вот у std::deque<T> итератор действительно есть.
    Ответ написан
    Комментировать
  • Собрать пример CURL-приложения C++11 в MVS2019?

    Nipheris
    @Nipheris Куратор тега C++
    У вас проблемы с линковкой, не настроены или неверно выбраны import-библиотеки или статические библиотеки (зависит от того, как вы планируете линковать libcurl к своему проекту-примеру).
    Также возможно неверно настроены определения комплиятора - некоторые библиотеки требуют задания констант препроцессора при динамической, или наоборот, статической линковке. Например, libcurl требует настройки CURL_STATICLIB при статической линковке.

    Все пакеты установлены из пакетного менеджера VS

    Закопайте эти библиотеки, проект CoApp, который был посвящён идее использовать NuGet для нативных (С/С++) библиотек, умер почти сразу после своего рождения, на границе 2014/2015 годов. Это очень старые версии, к тому же. Практика показала, что NuGet в большинстве случаев не годится для нативных библиотек (не буду расписывать, почему).

    Используйте для C/C++ проектов нормальные пакетные менеджеры вроде Conan или, на худой конец, Vcpkg. Там это всё уже предусмотрено. Впрочем, это не отменяет необходимости понимания простейших ошибок компилятора/линковщика и его основных опций.
    Ответ написан
    1 комментарий
  • Почему конструктор Class ( Class other) { } не может принимать объект своего типа по значению?

    Nipheris
    @Nipheris Куратор тега C++
    Потому что чтобы передать какой-либо агрумент по значению, его нужно скопировать. Чтобы скопировать аргумент, который является объектом класса, нужно вызвать конструктор копирования (неважно, сгенерирован ли он автоматически или вручную написан).

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

    Вроде должно быть понятно.
    Ответ написан
    2 комментария
  • Ссылка на неразрешённый внешний символ, что это и как исправить?

    Nipheris
    @Nipheris Куратор тега C++
    Я думаю, что вы создали консольное приложение вместо оконного. Можете пересоздать проект и выбрать Win32 Application в качестве шаблона, и поместить в него ваш код (рекомендую этот вариант), либо попробовать поменять подсистему с Console на Windows в настройках линковщика (скорее всего, ещё и точку входа нужно будет прописать вручну.).
    Ответ написан
    2 комментария
  • Что не так с наследованием?

    Nipheris
    @Nipheris Куратор тега C++
    Т.к. и базовый класс и класс-наследник являются шаблонными, то компилятор C++ считает, что члены класса mnoj являются так называемыми "зависимыми идентификаторами" (dependent names). Такие идентификаторы по-умолчанию не включаются в процесс разрешения имён и их нужно "затаскивать" в него явно.

    Вариант 1 (советую его): обращаться к полям базового класса через this: this->index - это вообще хорошая практика - сразу видно, где используется локальная переменная, а где идёт работа с состоянием объекта.
    Вариант 2: использовать using mnoj<T>::index; и using mnoj<T>::mas внутри описания класса mnoj1.
    Ответ написан
    3 комментария
  • Как вращать кривую Безье в функций на WinAPI?

    Nipheris
    @Nipheris Куратор тега C++
    1. Рисовать что-либо нужно в WM_PAINT. Но вы НЕ должны вызывать повторную инвалидацию в WM_PAINT, да и работать с таймером нежелательно.
    2. По срабатыванию таймера (т.е. или в WM_TIMER, или в колбэке, как вам удобно) нужно делать инвалидацию окна с помощью InvalidateRect или UpdateWindow. Вы НЕ должны рисовать в обработчике таймера.

    Почитайте ещё про виндовый механизм инвалидация-рисование, это критически важно для понимания происходящего. Вы не должны просить перерисовать что-либо напрямую. Вместо этого вы заявляете Винде, что вам больше "не нравится" какая-то область в окне (или всё окно целиком) и вы считаете эту область устаревшей и требующей обновления. Винда принимает это к сведению, и затем, через какое-то время, она пришлёт вам WM_PAINT, где вы всё нарисуете как считаете нужным.

    Это удобно тем, что например если окно скрыто, Винда не посылает вам WM_PAINT и вы ничего не рисуете вообще, экономя ресурсы машины.

    Если вы хотите добиться анимации, вам нужно регулярно (раз в N мс) заявлять Винде, что у вас устарело содержимое окна.
    Ответ написан
    Комментировать
  • Как прочитать весь http запрос вместе с телом?

    Nipheris
    @Nipheris Куратор тега C++
    async_receive:
    The receive operation may not receive all of the requested number of bytes. Consider using the async_read function if you need to ensure that the requested amount of data is received before the asynchronous operation completes.


    Но т.к. вы всё равно заранее не знаете, сколько байт вам нужно прочитать, я не вижу проблемы в поведении async_receive. Вам нужно отслеживать состояние вашего протокола (в вашем случае - HTTP) и понимать, когда нужно подождать ещё данных, а когда уже всё пришло.
    Ответ написан
    Комментировать
  • Как подключать библиотеки, используя MinGW?

    Nipheris
    @Nipheris Куратор тега C++
    Для начала хватит и того что Сергей Горностаев посоветовал, но вообще вам бы почитать про какую-нибудь сборочную систему, например про CMake, и про процесс подключения внешних зависимостей. Может быть даже стоит поинтересоваться Conan-ом или Vcpkg-ем.

    Вас ждёт много интересного.

    А, ну да, сначала лучше получить базовые знания о процессе сборки C/C++ программ. "Как я понял для этого нужна линковка" - вот этот момент нужно сильно улучшить. Иначе вы ещё долго будете страдать.
    Ответ написан
    1 комментарий
  • Как перехватить I/O потоки стороннего .exe?

    Nipheris
    @Nipheris Куратор тега C++
    Комментировать
  • Как добавить директорию поиска DLL для проекта C++ в VIsual Studio?

    Nipheris
    @Nipheris Куратор тега C++
    Вам необходимо добавить директории в переменную среды PATH. Это основной способ заставить загрузчик находить их помимо расположения рядом с EXE.

    Как добавить эти директории - это другой вопрос. Конкретное решение зависит от того, в какой среде вам это нужно и какие у вас ограничения. Например, Конан умеет создавать т.н. "среду для запуска" (run environment) и создаёт специальные батники, где прописывает за вас пути к DLL-кам в пакетах. Эти батники могут "активировать" среду, прописав всё что нужно в PATH (пути к нужным DLL), в результате чего EXE-шник, использующий их, сможет их найти (точнее, системный загрузчик сможет найти), и "деактивировать" среду, чтобы вернуть PATH в исходное состояние. Это просто вам для примера решение, может быть вам понравится идея и вы сделаете такие же батники для запуска на машине разработчика или юзера.
    Ответ написан
    Комментировать
  • Как собрать библиотеку .lib [muParser]?

    Nipheris
    @Nipheris Куратор тега C++
    Почему бы не посмотреть CI скрипты, например для AppVeyor?
    Версия с мастер-бранча :
    version: 1.0.{build}
    os: Visual Studio 2015
    clone_folder: C:\projects\muParser
    test: off
    branches:
      only:
        - master
    environment:
      matrix:
        - CMAKE_PLATFORM: Visual Studio 14 2015
    build_script:
      - cmake -LAH -G "%CMAKE_PLATFORM%" -DCMAKE_INSTALL_PREFIX="%CD:\=/%/install" .
      - cmake --build . --config Release --target install
      - ctest -C Release --output-on-failure

    Мне кажется вызовы cmake в конце (кроме ctest) будут вам полезны. Да, вместо CMAKE_PLATFORM можно указать другой генератор, например MinGW Makefiles.
    Ответ написан
    Комментировать
  • Как включить в статическую библиотеку все зависимости из других стат.библиотек в CMake проекте?

    Nipheris
    @Nipheris Куратор тега C++
    Господи, что ж тут за костыли насоветовали))

    Этого хотелось бы избежать, то есть нужно, чтобы все зависимости от boost были уже включены в mylib.

    Как верно отметил jcmvbkbc , обычно одна стат. библиотека не тащит в себе другую. Более того, такая возможность - включить одну стат. библиотеку в состав другой - мало где существует, я знаю про поддержку такой фичи только в Visual Studio. Ну т.е. это нечто из ряда вон выходящее, а не привычный workflow. По-нормальному вы должны указывать при линковке стат. библиотеки все её зависимости. Следовательно, вопрос в том, как эту информацию о транзитивных зависимостях статической библиотеки передавать и использовать при линковке с ней.

    pkg-config в общем вполне нормальное решение, но это уже не совсем "в рамках CMake".
    В рамках CMake всё делается с помощью target_link_libraries и экспорта симейк-конфига в паре с файлом симейковских таргетов. Например, вот такой незамысловатый скрипт:
    cmake_minimum_required(VERSION 3.5)
    find_package(Boost COMPONENTS system filesystem thread REQUIRED)
    add_library (mylib mysource.cpp)
    target_link_libraries(mylib
    	PRIVATE
    		Boost::system
    		Boost::filesystem
    		Boost::thread
    )
    
    install(TARGETS mylib EXPORT mylib_export)
    export(EXPORT mylib_export FILE cmake/mylib-targets.cmake)

    сгенерирует в поддиректории cmake в директории сборки файл mylib-targets.cmake, где помимо прочего будет следующая любопытная информация:
    # Create imported target mylib
    add_library(mylib STATIC IMPORTED)
    
    set_target_properties(mylib PROPERTIES
      INTERFACE_LINK_LIBRARIES "\$<LINK_ONLY:Boost::system>;\$<LINK_ONLY:Boost::filesystem>;\$<LINK_ONLY:Boost::thread>"
    )


    Таким образом, Симейк сообщает потребителям библиотеки mylib, что при линковке с ней нужно ещё добавить бустовские таргеты. Причём благодаря LINK_ONLY это коснётся только процесса линковки, в целом зависимость от библиотек буста будет приватной, как и указано в скрипте. Если поменять PRIVATE на PUBLIC и сделать тем самым зависимость от буста публичной, то LINK_ONLY уйдёт и будет обычное перечисление интерфейсных зависимостей таргета:
    # Create imported target mylib
    add_library(mylib STATIC IMPORTED)
    
    set_target_properties(mylib PROPERTIES
      INTERFACE_LINK_LIBRARIES "Boost::system;Boost::filesystem;Boost::thread"
    )


    Вам остаётся лишь добавить генерацию и установку тривиального конфига (где будет только find_package для буста и инклуд сгенерированного mylib-targets.cmake) и в потребителях делать find_package(mylib). Всё это кроссплатформенно и является стандартной практикой, не делайте лишних извращений со слиянием статических библиотек.
    Ответ написан
    Комментировать
  • Структура и зависимости кросс-платформерного проекта CMake?

    Nipheris
    @Nipheris Куратор тега C++

    Один из моих вариантов решения проблемы:
    Написать скрипт (скорее всего на python, ибо нужна возможность компилировать как из под Windows, так и из под Linux), который будет собирать все зависимости под конкретную платформу, раскидывать по папочкам и генерировать скрипт с путями ко всем нужным библиотекам.

    Поразительно, но вы в точности описали пакетный менеджер Conan (о котором упоминали).

    Написать скрипт (скорее всего на python, ибо нужна возможность компилировать как из под Windows, так и из под Linux)

    Конан написан на Питоне и распространяется как pip-пакет.

    который будет собирать все зависимости под конкретную платформу, раскидывать по папочкам

    https://docs.conan.io/en/latest/using_packages/con...
    Together, these folders are the local cache. This is where package recipes and binary packages are stored and cached, so they don’t have to be retrieved again.


    и генерировать скрипт с путями ко всем нужным библиотекам

    https://docs.conan.io/en/latest/reference/generato...
    Generators are specific components that provide the information of dependencies calculated by Conan in a suitable format for a build system. They normally provide Conan users with a conanbuildinfo.XXX file that can be included or injected to the specific build system.
    Ответ написан
    Комментировать
  • Как объединить общие зависимости для нескольких cpp файлов?

    Nipheris
    @Nipheris Куратор тега C++
    К ответу ittakir добавлю, что исключительно в целях снижения времени компиляции, пользуются такой штукой как precompiled headers, куда помещаются все те хедеры, которые РЕДКО меняются, но ЧАСТО используются (в большинстве cpp-шников). Например, хедеры стандартной библиотеки. В таких случаях common_types.h, о котором упомянул ittakir обычно и оформляется как прекомпилированный хедер.
    Ответ написан
  • Как обновить офсеты?

    Nipheris
    @Nipheris Куратор тега C++
    Ну предположу что надо разреверсить свежий клиент вовки и найти адреса нужных переменных.
    Ответ написан
    1 комментарий
  • Почему срабатывает точка останова?

    Nipheris
    @Nipheris Куратор тега C++
    int *mas = new int(size); // массив с числами

    Нет.
    Ответ написан
    1 комментарий