• Ошибка при создании явной специализации. В чём ошибка?

    @MarkusD Куратор тега C++
    все время мелю чепуху :)
    template <typename T>
    T maxn(T arr[], int arrSize);

    Это - общая форма шаблона функции. Если тебе нужно сделать явную специализацию шаблона, твоя явная специализация должна соответствовать этому общему шаблону.

    template <>
    const char* maxn(const char* arr[], int arrSize);

    Сырые однобайтовые строки в C++ (при соблюдении правила нуль-терминации) определяются типом char* или const char* если строку не планируется модифицировать. Наша функция не планирует модифицировать строки, следовательно явная специализация шаблона должна работать с типом const char*.
    Тип const char* должен быть подставлен везде вместо параметра шаблона T.

    Таким образом явная специализация шаблона для сырых строк будет полностью соответствовать общему шаблону функции.

    А теперь немного о твоей ошибке.
    template <> char* maxn(const char *arr[], int arrSize);

    Это объявление не является явной специализацией приведенного выше шаблона. Это - определение перегрузки функции через явную специализацию какого-то иного неописанного шаблона. Это потому что результат функции char* отличен от параметра функции const char*.
    В целом, эта запись является плохо сформулированной (ill-formed) по целому ряду причин, включая и то, что перегрузка не может осуществляться через изменение типа результата функции.

    В целях обучения я советую не опускать перечисление аргументов явной специализации шаблона:
    template <>
    const char* maxn<const char*>(const char* arr[], int arrSize);

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

    gbg
    @gbg Куратор тега C++
    Любые ответы на любые вопросы
    Потому что без такой инициализации невозможно:
    1) Передать параметры в базовые классы
    2) Инициализировать константы.
    3) Иметь поля, для которых нет умолчательного конструктора

    Если с первым вроде как понятненько, то второе требует уточнений. Без такой инициализации, все поля в классе должны сперва создастся при помощи умолчательного конструктора, а потом еще раз инициализироваться уже в теле конструктора. Это двойная работа, что нехорошо.

    Кроме того, для полей, у которых нет умолчательного конструктора, в таком случае, выходит что нет способа их адекватно создавать не на куче.
    Ответ написан
    5 комментариев
  • Длина файла в c++?

    @res2001
    Developer, ex-admin
    Не нужно вам так: for(i =0; i<=длина файла -1;i++)
    Читайте пока не будет eof() или ошибки, обычно делают примерно так:
    while(f.good()) { f.read() }

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

    gbg
    @gbg Куратор тега C++
    Любые ответы на любые вопросы
    Потому что вы передаете по значению (это означает, что функция получит копию аргумента), а надо передавать по ссылке:
    int input(TComplex& a, TComplex& b, TVect& first, TVect& second, float& one )
    {
    Ответ написан
    Комментировать
  • Почему мне видает nan?

    15432
    @15432
    Системный программист ^_^
    Синус/косинус может принимать только значения от -1 до 1

    у вас он почему-то 2.5
    Ответ написан
    5 комментариев
  • Имеет ли смысл в 2020-м году входить в веб?

    DevMan
    @DevMan
    большой рынок – большая конкуренция, но и гораздо больше возможностей.

    можно быть спецом в, например, оракле с десятком вакансий на страну и нормально зарабатывать.
    можно быть спецом в веб–деве, с тысячами вакансий, и нормально зарабатывать.
    а можно в обоих случаях быть посредственностью и сосать. все зависит только от вас.

    рональда, походу, веберы покусали или отпинали; его слушать – себя не уважать.
    Ответ написан
  • Какую книгу об оконных приложениях на C++ почитать?

    gbg
    @gbg Куратор тега C++
    Любые ответы на любые вопросы
    40083994-maks-shlee-qt-5-10-professionalnoe-programmirovanie-na-c-40083994.jpg
    Ответ написан
    Комментировать
  • Как в qt qml в создаваемом классе менять свойства qml объектов?

    Zifix
    @Zifix Куратор тега Qt
    Barbatum
    1. В реальном коде не используйте абсолютное позиционирование, кроме редких случаев
    2. У вас сейчас MouseArea имеет нулевой размер, надо использовать anchors.fill: parent
    3. В обработчике onClicked: backend.a вы сделали полную бессмыслицу, во-первых у бэкэнда нет такого свойства, во-вторых, вы его никак не изменили, и даже на экран не вывели.
    4. Для того, чтобы методы С++ класса стали доступны в QML, они должны быть в секции public slots

    В данном случае можно было бы добавить в бэкэнд свойство color, и его привязать к Rectangle, как color: backend.color. Ну и в onClicked уже вызывать backend.change(), которая обновит свойство.

    А вообще, читайте статьи, книгу, чужие исходники, и документацию, чтобы не возникало подобных элементарных вопросов.
    Ответ написан
    2 комментария
  • Найти цифру 7 в числе от 100 до 1000?

    myjcom
    @myjcom Куратор тега C++
    Нужно сгенерировать 15 чисел от 100 до 1000(включая дробные) и вывести 15 чисел в которых есть цыфра 7.

    Ну в 15 сгенерированных числах может и не быть 15 чисел с цифрой 7.

    spoiler

    #include <iostream>
    #include <vector>
    #include <string>
    #include <random>
    #include <algorithm>
    #include <iterator>
    #include <iomanip>
    #include <limits>
    using namespace std;
    
    // Не важно, пусть будет так.
    auto getNRandomNumbersVecFromRange(const double low, const double hi, const int n){
      random_device rd;
      mt19937 gen(rd());
      uniform_real_distribution<> dis(low, hi);
      vector<double> randNumbersVec(n);
      generate_n(randNumbersVec.begin(), n, [&dis, &gen]{ return dis(gen); });
      return randNumbersVec;
    }
    
    int main()
    {
      auto numbers = getNRandomNumbersVecFromRange(100.0, 1000.0, 15);
    
      cout << setprecision(numeric_limits<double>::digits10 + 1);
    
      copy(numbers.cbegin(), numbers.cend(), ostream_iterator<double>(cout, "\n"));
    
      cout << "\n" << "result:" << "\n"; // "\nresult\n"
    
      // А это важно --> to_string(n).find('7') != string::npos
    
      copy_if(numbers.cbegin(), numbers.cend(),
              ostream_iterator<double>(cout, "\n"),
              [](auto n) { return to_string(n).find('7') != string::npos; });
    }

    Ответ написан
    1 комментарий
  • Обьявление и Определение Шаблона метода?

    xorknown
    @xorknown
    Будут проблемы - решайте
    Если не вдаваться в подробности компиляции, то можно, но есть свои ограничения. Если вы хотите запихнуть реализацию шаблона в cpp файл, то вам надо инстанцировать его после реализации, чтобы компилятор мог использовать ее в других файлах(в который вы включили хэдер с объявлением). Если хотите перенести реализацию в другой хэдер, то вам необходимо включать его во всех cpp файлах где вы хотите его использовать.

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

    @res2001
    Developer, ex-admin
    Можно делать примерно так:
    #include <cfloat>
    ...
    if (res > -DBL_EPSILON && res < DBL_EPSILON) res = 0;
    cout << res;

    В качестве DBL_EPSILON вы можете выбрать другое число, которое вам более удобно.
    Красиво тут не получится. Так же как бесполезно делать точное сравнение (==) двух чисел с плавающей точкой.
    Ответ написан
    2 комментария
  • MacOS как показать док на нужном мониторе слева?

    DevMan
    @DevMan
    между мониторами можно перекидывать док только в нижнем положении.
    поэтому или смиритесь, или разместите док внизу, или ищите сторонние утилиты управляющие доком или заменяющие его.
    Ответ написан
    Комментировать
  • Разработка Qt - структура Qt-приложения.?

    @tugo
    Посмотрите это видео. Вот так, для начала, должна выглядеть структура вашего приложения.
    1. Для построения графического интерфейса пользуйтесь Qt Designer (а не размещая врукопашную виджеты, как это делаете вы).
    2. В первом, самом простом приложении, должно быть 4 файла исходных кодов.
    main.cpp
    MainWindow.h
    MainWindow.cpp
    MainWindow.ui
    // MainWindow.h
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        explicit MainWindow(QWidget * parent = 0);
        ~MainWindow();
    
    signals:
    
    protected:
    
    private:
        Ui::MainWindow * ui;
    };


    3. Если количество элементов в MainWindow становится слишком большим, выделяйте элементы в отдельные классы, наследники класса QWidget.
    Допустим, у вас в MainWindow расположен элемент Tab Widget, в котором 2 вкладки.
    Логично вынести логику работы элементов в каждой вкладке в свой класс, т.е. у вас в проекте должно появиться еще 6 файлов:
    MyTabWidget1.h
    MyTabWidget1.cpp
    MyTabWidget1.ui

    MyTabWidget2.h
    MyTabWidget2.cpp
    MyTabWidget2.ui

    // MyTabWidget1.h
    #pragma once
    
    #include <QWidget>
    
    namespace Ui {
    class MyTabWidget1;
    }
    
    class MyTabWidget1: public QWidget
    {
        Q_OBJECT
    
    public:
        explicit MyTabWidget1(QWidget * parent = 0);
        ~MyTabWidget1();
    
    private:
        Ui::MyTabWidget1* ui;
    };


    В классе MainWindow используются объекты классов MyTabWidget1 и MyTabWidget2.
    Логика работы MainWindow резко похудеет, все перенесется в MyTabWidget1 и MyTabWidget2.

    4. Дальше. Избегайте реализации логики работы класса GUI. Эти классы (MyTabWidget1 и MyTabWidget2, MainWindow) должны быть простыми прокладками, трансляторами сигналов от пользователя в логику работы приложения и визуализаторами состояния приложения пользователю.
    Начинаете логику работы приложения реализовывать в отдельном классе.
    Обмен информацией между Logic <--> MainWindow возложите на сигналы-слоты.
    Ответ написан
    Комментировать
  • Как сделать рандомный вывод из файла c++?

    #include <iostream>
    #include <string>
    #include <fstream>
    #include <time.h>
    
    using namespace std;
    
    int main() {
        srand((unsigned int)time(0));
    
        int n = 10; // количество строк в файле
    
        int random = rand() % n + 1;
    
        ifstream in("test.txt");
        string result;
    
        for (int i = 0; i < random; i++) {
            getline(in, result);
        }
    
        cout << result << endl;
    
        system("pause");
        return 0;
    }
    Ответ написан
    2 комментария