pair в данном случае наиболее очевидный и естественный способ достичь желаемого. На функциональном языке однозначно именно так бы и было сделано.
В данном конкретном случае, пожалуй, я бы тоже выбрал пару - вполне естественным представляется первым элементом написать результат деления, а вторым - остаток, но вообще, лично я в случае однотипных значений, чтобы не перепутать, что первое, а что второе (третье и т.д., если с std::tuple) предпочитаю оборачивать возвращаемый результат структурой - именованные поля не дадут запутаться.
-- Fri Apr 05, 2019 14:33:11 --И может ради быстродействия писать сколь угодно длинные коды.
Иногда да - и код может стать неудобочитаемым и появляются ассемблерные вставки ради быстродействия, но вы начали с конца - поставили телегу впереди кобылы: сначала пишется код, который хорошо структурирован, удобочитаем, легко понимаем, а уже потом, если с этим кодом возникают проблемы, связанные с быстродействием, проводится его анализ, выявляются узкие места, возможно меняются алгоритмы (не везде подряд, а только в узких местах - если, скажем, программа вызывает 2 функции, одна из которых занимает 99% времени, а вторая 1%, то ускорение даже в 100 раз второй, если это снизит ее удобство поддержки и использования/надежность, противопоказано), возможно, меняется архитектура целиком, чтобы избежать этих узких мест, а уже потом, если все еще остается необходимость, возможна микрооптимизация. Интересно, что во многих случаях с современными компиляторами и современными процессорами приемы этой микрооптимизации, которые могли быть актуальны в 90-е, сейчас не имеют смысла - компилятор сам соптимизирует, и уж, конечно, при анализе производительности смотреть можно только на релизный вариант - тот, в котором компилятор эти оптимизации делает. Поэтому важно: а) собирать релизную версию; б) указывать ключи оптимизации (-O2, -O3 и т.п.), в) указывать, на каком железе проводилось тестирование.