• Как с помощью шаблонов проверить, что два числа равны?

    @MarkusD Куратор тега C++
    iihaarr, не забывай ставить уведомления, это сделать очень просто - кнопкой "Ответить".
    Ты сейчас задал один вопрос, а решить тебе надо совсем другую проблему.

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

    @MarkusD Куратор тега C++
    iihaarr , покажи пример, как конкретно ты хочешь использовать свой шаблон.
    В каком виде у тебя задаются эти два числа, которые тебе надо сравнить?
  • Зачем в стандартной библиотеке вначале класса объявлены псевдонимы для параметров шаблона?

    @MarkusD Куратор тега C++
    Dolarun, да, это широко распространенная практика. Но я не смог понять с твоих слов того, что ты говоришь об этом коде.
    Твой пример - это определение вложенных типов, которые зависят от параметров шаблона.

    Чтобы понять пользу таких определений, просто представь ситуацию. У тебя есть вектор элементов MyVector. Ты знаешь что этот вектор инстанцирован из шаблона std::vector, но не знаешь тип элементов этого вектора потому что тип уже 10 раз менялся в процессе рефакторинга.
    Тебе достаточно использовать MyVector::value_type чтобы узнать тип элемента вектора.
    Польза становится только больше очевидной когда ты работаешь над кодом шаблона алгоритма, в котором используется абстрактная коллекция из шаблонного параметра, у которой по контракту должен быть все тот же вложенный тип value_type.

    В общем и целом это относится к принципу единственной зависимости из SOLID. Ты замыкаешь свой код на зависимость от одного типа вместо зависимости от множества разных типов, имена которых могут измениться в процессе рефакторинга.
  • Что за Adb.exe и какое отношение он имеет к unity?

    Zefirot , adb - это Android Debug Bridge. Это сервис для связи с телом на андроиде при прямом подключении по USB.
    Его используют средства автоматизации для взаимодействия с подключенным телом. Также его используют разработчики для все того же взаимодействия с телом.
    Подробности тут.

    Unity, будучи массивным средством автоматизации, поднимает его при всяком удобном случае чтобы тебе не пришлось ждать лишние 1.5 секунды когда ты захочешь залить сборку в тело.
  • Как сделать, чтобы шаблонная функция принимала const char*?

    @MarkusD Куратор тега C++
    Mercury13,
    Лучшее решение
    namespace str
    {
    namespace Internal
    {
        template< typename TChar, typename TCharTraits >
        inline std::basic_string_view<TChar, TCharTraits> remainderSv( 
            const std::basic_string_view<TChar, TCharTraits> source,
            const std::basic_string_view<TChar, TCharTraits> prefix
        )
        {
            if( source.length() <= prefix.length() || !source.starts_with( prefix ) )
            {
                return {};
            }
    
            return source.substr( prefix.length(), source.length() - prefix.length() );
        }
    
        template< typename TSource >
        inline auto GetView( const TSource& source )
        {
            return std::basic_string_view{ source };
        }
    
        template< typename TChar, typename TCharTraits, typename TAllocator >
        inline std::basic_string_view<TChar, TCharTraits> GetView( 
            const std::basic_string<TChar, TCharTraits, TAllocator>& source 
        )
        {
            return source;
        }
    }
    
    
        template< typename TSource, typename TPrefix >
        inline auto remainderSv( const TSource& source, const TPrefix& prefix )
        {
            return Internal::remainderSv( Internal::GetView( source ), Internal::GetView( prefix ) );
        }
    }


    Тебе не нужна здесь универсальная ссылка. Ты говорил что активно внедряешь 20й стандарт, значит тебе стоит пользоваться благами 17-го и 14-го стандартов, а не писать автоматический код за транслятор. Здесь нет ни одного избыточного шаблона. Этот remainderSv потребляет любую комбинацию согласованных типов строк, а на недопустимой комбинации просто не может инстанцировать Internal::remainderSv.
    Этот код просто понятен и не вызывает вопросов.
  • Как сделать, чтобы шаблонная функция принимала const char*?

    @MarkusD Куратор тега C++
    Mercury13,
    Ведь в нешаблонную функцию подставляет, верно?

    Нет, не верно. Поиск имен подбирает, а не подставляет. Поиск подбирает лучшее соответствие исходя из возможности сужающего преобразования типа.
    Это делается тогда, когда вариантов без сужения не находится.

    С сигнатурой из вопроса функцию из шаблона инстанцировать получится только при явном определении параметров шаблона. В этом случае начнет работать сужающее преобразование.

    Код в текущем решении плохой. Ты боишься за инстанцрование лишних функций, а сам написал гору частичных специализаций шаблона.
    Можно сделать проще и понятнее - на базе всего нескольких шаблонов. Я чуть погодя покажу, следующим комментарием.
  • Как сделать, чтобы шаблонная функция принимала const char*?

    @MarkusD Куратор тега C++
    Mercury13 , я ведь правильно понимаю что тебе хочется чтобы из этого шаблона можно было инстанцировать функции с сигнатурой, например, std::string_view ( const char*, std::string_view ) или
    std::string_view ( const std::string&, const std::string& )
    ?
    Иначе я немного не понимаю твой вопрос.

    Сужающие конверсии через поиск имен доступны только когда инстанцирование уже произведено и функция из шаблона есть в списке кандидатов.
  • Как откатить права к файлам в git?

    Сергей Кузнецов, ну до git push я не дочитал. ))
    Смертный грех - это то, за что смерть сразу как сделал. Например если зажать в зубах фазу и взяться за батарею руками.
    А git push --force я и сам делал когда было нужно.
  • Как откатить права к файлам в git?

    yellow_pus, а почему ты игнорируешь мой комментарий прямо под своим вопросом?
    И почему здесь в комментариях обращаешься ко мне, а не к Сергей Кузнецов? :)
    Я ведь ничего тут кроме уточнений не написал.

    Выхода у тебя два, в зависимости от твоего ответа на мой комментарий под вопросом. Если коммит у тебя локальный - просто удали его так, как советует Сергей Кузнецов.
    Если коммит у тебя ушел в удаленный репозиторий, сделай откат изменений по этому коммиту любым удобным из десятков способов.
  • Как откатить права к файлам в git?

    Сергей Кузнецов, не стоит утверждать того, что имел в виду скорее всего, или не скорее всего, автор или просто другой человек.
    У тебя ответ все равно не отвечает на вопрос. В чем-то он верен, но не в решении вопроса.
    Не думай за других, спрашивай других. Разбираться стоит в их ответах на твои вопросы, а не в своих подозрениях.

    С другой стороны, автор похоже не заинтересован в коммуникациях и решении своей проблемы. На вопросы он отвечать не стремится совсем.
  • Как откатить права к файлам в git?

    Сергей Кузнецов , гит хранит права к файлам. По умолчанию хранит. Эту функцию, чтобы не хранил, надо принудительно отключать через git config core.fileMode false.
  • Как откатить права к файлам в git?

    yellow_pus , коммит у тебя локальный или уже в наружу ушел?
  • Не подключается C++ библиотека в Visual Studio 2022, в чём причина?

    @MarkusD Куратор тега C++
    Rag’n’ Code Man, случайным образом ты в проблеме разобрался через одно место.
    Скриншоты свойств ты привел, но бестолково. От них нет никакой пользы в вопросе.
    Если бы ты привел скриншоты всего окна свойств проекта, то там стало бы видно что все твои настройки указаны только для Win32 Debug, надо полагать. А собираться ты надумал в X64.
    Вот и все твои проблемы. Настройки ты задал для одной платформы, а собирался - в другой.
  • Как правильно освобождать память?

    @MarkusD Куратор тега C++
    calculator212, у тебя довольно хорошо получается решать проблему. Давай я только немного подправлю твои действия.

    Для размерных величин int очень плохо подходит. Для этих целей в стандартной библиотеке есть тип size_t[?].
    Дополнительно, стандарт C++11 позволяет нам сегодня использовать инициализацию полей по месту их определения. Этими вещами полезно пользоваться.
    Определение состояния
    template< typename TValue >
    class Array final
    {
    private:
        TValue* m_memory    = nullptr;
        size_t  m_length    = 0;
    };


    При таком определении полей код инициализации можно изрядно сократить используя default там где это можно.
    C++11 вводит термин перемещения ресурса. Поэтому правило теперь называется не "Правило 3", а правило "3/5/0".
    Следуя правилу 3/5/0
    public:
        inline Array()  = default;
        inline ~Array() { delete[] m_memory; };
        
        explicit inline Array( const size_t length );
        
        inline Array( const Array& other );
        inline Array( Array&& other );
        
        inline Array& operator = ( const Array& other );
        inline Array& operator = ( Array&& other );


    Логика копирования должна быть какой? У тебя массив, в нем данные. Массив копируется. Значит данные тоже надо скопировать.
    Обрати внимание на то, что конструктор копирования использует синтаксис делегирующего конструктора чтобы передать конструктору преобразования требуемую длину массива.
    Конструктор копирования
    template< typename TValue >
    inline Array<TValue>::Array( const Array<TValue>& other )
        : Array{ other.m_length }
    {
        for( size_t index = 0; index < m_length; ++m_length )
        {
            m_memory[ index ] = other.m_memory[ index ];
        }
    }


    Если конструктор копирования работает в создаваемом объекте, то оператор копирования работает только в уже созданном объекте. Т.е. в момент работы оператора копирования объект же находится в каком-то состоянии. И это состояние нужно правильно завершить, согласно логике работы твоего шаблона.
    Оператор копирования
    template< typename TValue >
    inline Array<TValue>& Array<TValue>::operator=( const Array<TValue>& other )
    {
        if( m_length != other.m_length )
        {
            delete[] m_memory;
            m_length = other.m_length;
            m_memory = new TValue[ m_length ];
        }
        
        for( size_t index = 0; index < m_length; ++m_length )
        {
            m_memory[ index ] = other.m_memory[ index ];
        }
        return *this;
    }


    Термин перемещения означает буквально перенос состояния из одного объекта в другой. И если копирование приводит к повторному выделению памяти в твоем шаблоне, то перемещение уже не должно.
    В этом и суть перемещения.
    Перемещение
    template< typename TValue >
    inline Array<TValue>::Array( Array<TValue>&& other )
        : m_memory{ std::exchange( other.m_memory, nullptr ) }
        , m_length{ std::exchange( other.m_length, 0 ) }
    {
    }
    
    template< typename TValue >
    inline Array<TValue>& Array<TValue>::operator=( Array<TValue>&& other )
    {
        delete[] m_memory;
        m_memory = std::exchange( other.m_memory, nullptr );
        m_length = std::exchange( other.m_length, 0 );
        return *this;
    }


    Ну и на последок, еще осталось только конструктор преобразования определить.
    Конструктор преобразования
    template< typename TValue >
    inline Array<TValue>::Array( const size_t length )
        : m_length{ length }
    {
        if( m_length == 0 )
        {
            return;
        }
        
        m_memory = new TValue[ m_length ];
    }


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

    @MarkusD Куратор тега C++
    Pinkman, тебе стоит более точно сформулировать вопрос.
    Тебя интересуют именно все целочисленные и вещественные числа или тебя интересуют исключительно только int и double?

    Ты сейчас свой вопрос поставил так, как будто спрашиваешь разрешение решить задачу каким-то определенным образом.
    Но саму задачу ты не описал еще. Я предлагаю тебе описать в своем вопросе именно условия решаемой тобой задачи.
  • Как написать explode() на c++?

    @MarkusD Куратор тега C++
    RabraBabr,
    По значению?

    Да, по значению. А в чем сложность передать одно целочисленное значение в общем регистре ЦП?

    Каждый раз будет копирование?

    Копирование чего и куда?

    O'k возьмем код попроще

    Этот код при передаче в библиотеку будет выкинут и написан новый, уже без лишних выделений памяти и неподобающих инициализаций.
  • Как написать explode() на c++?

    @MarkusD Куратор тега C++
    Wataru, вопрос строки input.find(separator, i); я просто не стал обозначать. Как и вопрос чрезмерного выделения памяти. Я только ответил человеку относительно length внутри цикла.
  • Как написать explode() на c++?

    @MarkusD Куратор тега C++
    RabraBabr,
    То есть оно вызовется только один раз независимо от количества циклов?

    Ответ на этот вопрос лежит в области работы оптимизатора. Результат действительно может быть таким, что length будет вызван только один раз для неизменяемой строки.

    Но код в ответе написан настолько нехорошо, что я могу говорить только о том, что вызывать length на каждой итерации - это не проблема для производительности. Метод просто возвращает значение поля длины строки. Никаких подсчетов фактической длины при этом не производится. Об этом и говорит сложность O(1) для этого метода.
  • Как написать explode() на c++?

    @MarkusD Куратор тега C++
    Issue, рекомендую изучить этот ответ.
    Если примешь во внимание все написанное там, тебе станет проще решать подобные заданному вопросы.