Здравствуйте, Аноним, Вы писали: А>В статье по реализации делегатов на С++ надо было получить лексему через макросы: А>
А>К чему здесь COMBINE1? Я согласен, что в ином случае код не компилиться... А>Вроде бы вот что происходит: А>1) Строчка А>
А>меняеться на А>
А>2) Потом, когда в где-нибудь в коде встретиться I_DELEGATE (или др.), то выполниться макром А>
А>но ведь если a — это I_DELEGATE и b — это 5, то вполне возможно написать и такое: А>
А>Но я уверен, что заюлуждаюсь, т.к. это неправельно... Зачем все-таки нужен этот промежуточный макрос? Читай 16.3.1/1. Если некоторые вхождения некоторых параметров макроса являются операндами операторов '##' или '#', то внутри этих вхождений не производится раскрытие макросов (которые могут там содержаться). Предположим, макрос 'COMBINE' объявлен вот так
и пытаемся применить этот макрос со следующими аргументами
При выполнении макроподстановки параметров 'a' и 'b' макроса 'COMBINE' препроцессор позаботится о том, чтобы выполнить раскрытие макросов, содержащихся в параметрах 'a' и 'b', только в первых вхождениях этих параметров, и 'a b' будет заменено на '10 20'. А вот для вторых вхождений такого раскрытия делаться не будет, т.к. эти вхождения являются аргументами оператора '##', и 'a##b' будет заменено на 'ARG1ARG2'. Финальный результат будет таким: '10 20 ARG1ARG2'. В большинстве случаев это не то, что нужно. Чтобы избежать вышеописанной проблемы применние оператора '##' выносят из основного макроса путем введения промежуточного макроса
Теерь при выполнении макроподстановки макроса 'COMBINE' все параметры будут полностью раскрыты, т.к. ни один параметр не соседствует с оператором '##'. 'COMBINE(ARG1, ARG2)' заменится на '10 20 COMBINE1(10,20)'. Далее произойдет раскрытие макроса 'COMBINE1' и финальный результат будет иметь вид '10 20 1020'. Вот поэтому в твоем случае и применен двухуровневый макрос. |