• Почему make file компилятора выдает ошибку, что функция переопределяется?

    CityCat4
    @CityCat4
    Внимание! Изменился адрес почты!
    Да, в общем-то русским (английским) по черному написано - data_process.c включает data_process.h, который первым определил функцию normalization().
    А потом сам data_process.c определил функцию normalization() чуть пониже - ессно компилятор выдает замечание о переопределении, ибо оно есть :)
    Ответ написан
    Комментировать
  • Возможно ли присвоить «ничего» в ссылку?

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

    В вашем коде 2 проблемы. = default; можно писать, если у вас нет никакого списка инициализации. И константную ссылку нельзя использовать для инициализации неконстантной.

    Вот такой код компилируется:
    template<typename T>
    struct Test
    {
        T& ref;  // нужно присвоить null
    
        Test(T& _ref) : ref(_ref) {};
    };
    Ответ написан
    3 комментария
  • Есть ли фриланс на С++ с нуля?

    TrueBers
    @TrueBers
    Гуглю за еду
    C++ -- инструмент, а не цель.

    "Если у меня есть молоток, то какие типы гвоздей мне им забивать?"

    На C++ можно писать ОС, игры, прикладные программы, системные утилиты, драйверы, прошивки, серверы, базы данных, да хоть чёрта лысого.
    Что интересно самому, тем и занимайся. C++ тут не причём, это 10% от всего, что нужно изучать.

    Большинство заказчиков на фрилансе вообще не шарят за языки и технологии. Им важно, чтобы задача была выполнена, а на чём ты её напишешь, большинству обычно всё равно.
    Ответ написан
    2 комментария
  • Как реализовать приоритетную очередь с функциями extractMax и add, которая поддерживает одинаковые элементы?

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


    Если нумерация массива идет с 1, то два ребенка элемента i будут 2*i и 2*i+1. У вас же нумерация с 0, т.ч. у вас дети - 2*i+1 и 2*i+2.

    Первое условие достигается правильной расстановкой строгого и нестрогого неравнества в условиях в алгоритме.

    Похоже, проблема в том, что у вас нумерация с 0 и, если новый элемент оказывается итак максимальным, вы вернете индекс 0, вместо нужного 1. Если вы элемент вниз просеиваете, то у вас там +1 стоит в res.first, но изначально у вас-то там 0.

    Далее, вы вектор неправильно используете. Вы делаете reserve и потом работаете с пустым вектором, как-будто он фиксированного размера. Вам надо делать resize вместо reserve. Или еще лучше, вместо вашей переменной size вы используйте arr.size(). При изменении размера массива делайте pop_back() и push_back().
    Ответ написан
    8 комментариев
  • Что быстрее индексы или указатели?

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

    Практический совет - лучше писать через индексы, ибо так понятнее и больше шансов что компилятор там все наоптимизирует (например, он сможет векторизовать работу через какие-нибудь SSE инструкции процессора).

    Совет по бенчмарку - если памяти не хватает, стоит по одному достаточно большому массиву пройтись 10000 раз. А лучше использовать готовые фреймворки для измерения скорости, вроде того де gbenchmark.

    Еще, иногда полезно посмотреть на ассемблерный выхлоп. Вот, например, что происходит при -O3 опции компилятора. Он генерирует вообще идентичный код для обеих функций (развернув циклы)! И даже при -O2 оно одинаковый код выдает.

    Без оптимизаций код разный, но там все не так как вы думаете. Вместо инструкции mov eax, dword ptr [rax + 4*rcx] в варианте с индексами используется инструкция mov eax, dword ptr [rax] для указателей. Это самое "складывание с указателем массива" вообще не отдельная операция - а вариант адрессации в инструкции mov. Они могут вообще одинаковое количество тактов занимать, это надо мануал по конкретной архитектуре процессоров читать.
    Ответ написан
    Комментировать
  • Что стоит учить с или c++ или c#?

    mindtester
    @mindtester Куратор тега C#
    http://iczin.su/hexagram_48
    или по вкусу.. или оба! .. понимание различий даст быстрый рост многих пониманий ;)))
    PS
    Надо ли учить Си? Или может лучше начать с C#, а дальше уже выучу C++?
    уже три разных языка.. мое мнение - если хватит азарта, учите все ;)))
    .. и все внимание на различия областей применений и возможностей ;)))
    Ответ написан
    1 комментарий
  • Что делать, если программа не видит библиотеку iostream?

    sergey-gornostaev
    @sergey-gornostaev Куратор тега C
    Седой и строгий
    Понять, что C и C++ - это два разных языка, и либо использовать C++, либо не использовать iostream.
    Ответ написан
    Комментировать
  • Как прикрепить в вопрос объёмный код?

    sergey-gornostaev
    @sergey-gornostaev
    Седой и строгий
    Не прикреплять объёмный код, всё равно никто не будет вычитывать, здесь не фриланс. Вместо этого стоит прикрепить минимальный воспроизводимый пример. Часто при попытке создания такового потребность в вопросе вообще отпадает.
    Ответ написан
    Комментировать
  • Почему tellg() неявно приводится к int при инициализации int, но не может быть сложенным с int?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Очевидно, потому что возвращаемый тип имеет определенный оператор преобразования к int или long, но не имеет переопределенного operator+ с int.

    Если смотреть описание возвращаемого типа, то там есть operator+ с каким-то streamoff, а с int - ничего нет. Там, правда, не указано, что есть опретор преобразования к int, так что это, наверно, тоже лучше не использовать.
    Ответ написан
    Комментировать
  • Как получить адрес памяти переменной в массиве, а не адрес индекса массива?

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

    Edit: и вы через массив к исходному line никак не обратитесь, только если не смените тип массива на Figure*
    Ответ написан
    Комментировать
  • Как извлечь элементы многобайтового массива как единое число?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Лучше так делать не надо. Это UB - нарушение всяких strict aliasing, выравниваия и вообще от порядка байт в машине зависит. Лучше руками собрать ULL по частям, вроде
    for (int i = 0; i < 8; ++i) result |= byte_array[i+1] << (8ULL*i);
    или
    for (int i = 0; i < 8; ++i) result |= byte_array[i+1] << (8ULL*(7-i));


    На худой конец, если очень узкое место, надо делать memcpy из массива в &result.
    Ответ написан
    Комментировать
  • Почему явная специализация невозможна?

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

    Если вы перенесете специализацию шаблона rewrite вверх, до специализации search, то все скомпилируется. Или надо где-то выше первого использования шаблона rewrite задекларировать специализацию (что ваш закомментированный код и делает).

    Вызвана эта ошибка стандартом.
    Надо, чтобы специализация шаблона была задекларирована до любого использования:
    Specialization must be declared before the first use that would cause implicit instantiation, in every translation unit where such use occurs:
    Ответ написан
    1 комментарий
  • Что быстрее: создание вектора push_back или сначала объявление сколько в нем переменных, а потом заполнение?

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

    Но push_back не на порядок медленнее. В худшем случае в пару раз. И то и другое будет работать за O(n). Если у вас программа еще хоть что-то делает, кроме запихивания чисел в массив, то вы разницу особо и не заметите.

    Если только профайлер не показывает что вот это вот самое медленное место в программе, то заморачиваться не стоит.
    Ответ написан
    3 комментария
  • Можно ли в c++ реализовать new() с c#?

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

    @dima20155
    you don't choose c++. It chooses you
    Полагаю, что вам удобно будет использовать здесь шаблоны, если я правильно понял вопрос.
    Например:
    template <typename T>
    auto search (std::string str) {
        // T - data type
        T res;
        // do something
        return res;
    }
    
    int main () {
        auto a = search<int>("a");
        auto b = search<std::string>("a");
    }
    Ответ написан
    5 комментариев
  • Почему вылазит link error(не видит вирутальные методы?)?

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

    Надо или весь класс определять в хедере, или в array.cpp указывать компилятору генерировать инстанс шаблона с параметром, который нужен в другом cpp файле:
    using Array<int>;

    То же и для очереди.

    Происходит это потому, что компилятор генерирует шаблоны лениво - только когда они нужны. Вот, компилируя array.cpp он не видет вообще ни одного использования шаблона и не генерирует ничего. В каком-нибудь main.cpp у него есть объявление из array.h и использование шаблона. Он и генерирует объявления методов. Но определения-то нигде нет. Оно в array.obj должно быть по вашему замыслу, а там пусто.
    Ответ написан
    1 комментарий
  • Как убрать предупреждение "F может быть равно NULL"?

    TrueBers
    @TrueBers
    Гуглю за еду
    Как минимум, не мешать Си и Си++, а писать на чём-то одном, и различать их.
    Во-вторых, зачем от предупреждения избавляться? Его нужно понять, почему оно появляется. Когда будет понимание, тогда всё станет на свои места.

    Достаточно предположить, что функция fopen_s внезапно не сможет открыть файл и вернёт ошибку. Допустим, файла не существует, или на его открытие нет прав у пользователя. Ты же не проверяешь возврат результата из функции открытия и пытаешься что-то записать в F, даже если функция не смогла открыть файл и вернула ошибку. А когда она вернёт её, переменная F останется нулевыем указателем или, в первом твоём случае, вообще будет обращение к неинициализированной переменной, где ты получишь неопределённое поведение. Вот оно и ругается на эту ветку развития событий.

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

    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 комментарий
  • Почему типы из заголовка cstdint доступны без его включения?

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

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