Компилятор на самом деле не выполняет никаких расширений макросов. Это задача препроцессора. Все это выглядит как один шаг, но компилятор фактически выполняет отдельные задачи препроцессора и перехватывает вывод для вас.
Шаблоны не «раскрываются» во время компиляции. Они создаются при использовании во время компиляции. Разница в том, что компилятор сразу генерирует объектный код для шаблона; нет промежуточного исходного кода, который выходит. Вы не можете рассматривать созданный экземпляр шаблона как исходный код, он выгружается как сборка, когда это необходимо.
Если у вас есть GCC, вы также можете напрямую вызывать препроцессор, используя 'cpp' с правильными аргументами (в основном это пути и определения макросов командной строки). Другие ответили на MSVC.