• Что означает запись?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    В контроллере COM-порта несколько регистров. Запись в них определённых значений меняет режим работы порта. Эти регистры адресуются от базового адреса контроллера.
    _outp(COMBase+3,0x80); - Line Control Register (LCR). Установка старшего бита разрешает доступ к делителю.
    _outp(COMBase,0x01); - установка младшего байта делителя (0x01 => 115200 tick/s).
    _outp(COMBase+3,0x03); - отключение доступа к делителю и установка размера символа 8 бит, 1 стоп-бит, без контроля чётности.
    _outp(COMBase+1,0x00); - Inerrupt Enable Register (IER), запрет всех прерываний.
    _outp(COMBase+2,0xC7); - FIFO Control Register (FCR), разрешить буферы FIFO размером 14 байт и очистить их.
    _inp(COMBase); - прочитать байт из буфера.
    www.osdever.net/documents/CP_serial.pdf
    Ответ написан
    Комментировать
  • Каков путь UX/UI дизайнера?

    sergey-gornostaev
    @sergey-gornostaev
    Седой и строгий
    На фрилансе развития или вообще нет или мизерное и медленное в сравнении с ростом в офисе. Я об этом здесь пишу много лет. Например: раз, два, три, четыре, пять и шесть. И делаю это со знанием дела, так как несмотря на (не побоюсь этого слова) талант к самообучению, в свои фрилансерские периоды в развитии практически останавливался. Эксперимент проводился многократно на протяжении 23 лет.
    Ответ написан
    Комментировать
  • Как отключить определение функции через шаблоны?

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

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

    И вот как это должно выглядеть в идеале.
    template< size_t ROWS, size_t COLUMNS >
    struct Matrix final
    {
    	template< size_t R = ROWS, size_t C = COLUMNS >
    	inline std::enable_if_t<R == C, int> GetDeterminant() const
    	{
    		return 0;
    	}
    };


    Важно гарантировать зависимость выражения SFINAE от параметров шаблона метода. Поэтому объявление шаблона выглядит именно так, а не как-то еще.

    Теперь, что будет если GetDeterminant не удалось вывести из шаблона? Будет ошибка трансляции, говорящая о том, что метод не найден. Это ничего не говорит пользователю. Это просто инструктирует транслятор остановить трансляцию. Пользователь, особенно если он не искушен знаниями о SFINAE, не сможет понять причину ошибки трансляции. Такая ситуация создаст риск излишней траты времени на дознание причин ошибки.
    Под конец выяснится что матрица просто не квадратная.
    Пользователю нужно объяснить причину отсутствия метода.

    Есть простой способ сделать это.
    template< size_t ROWS, size_t COLUMNS >
    struct Matrix final
    {
    	template< size_t R = ROWS, size_t C = COLUMNS >
    	inline std::enable_if_t<R != C, int> GetDeterminant() const = delete;
    
    	template< size_t R = ROWS, size_t C = COLUMNS >
    	inline std::enable_if_t<R == C, int> GetDeterminant() const
    	{
    		return 0;
    	}
    };


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

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

    И делается это крайне просто.
    template< size_t ROWS, size_t COLUMNS >
    struct Matrix final
    {
    	inline int GetDeterminant() const
    	{
    		static_assert( ROWS == COLUMNS, "Matrix should be square to calculate the determinant." );
    		return 0;
    	}
    };


    SFINAE в решении вопроса вообще не нужен. Он только больше усложнит конструкцию и будет запутывать.
    Достаточно простого статического утверждения с максимально детальным пояснением для пользователя.
    Для всех квадратных матриц метод детерминанта будет выведен без проблем. Для любой неквадратной матрицы вывод метода детерминанта провалится на проверке статического утверждения, а пользователь получит максимально конкретную причину провала.
    Ответ написан
    Комментировать