Какова цель оператора ## в C ++ и как он называется? - PullRequest
5 голосов
/ 14 июля 2009

Я просматривал проект DXUTCore, который поставляется с DirectX March 2009 SDK, и заметил, что вместо создания обычных методов доступа они использовали макросы для создания универсальных средств доступа, аналогично следующему:

#define GET_ACCESSOR( x, y )  inline x Get##y()  { DXUTLock l; return m_state.m_##y;};
...

GET_ACCESSOR( WCHAR*, WindowTitle );

Кажется, что оператор ## просто вставляет текст из второго аргумента в макрос, чтобы создать функцию, работающую с переменной, использующей этот текст. Это что-то, что является стандартным в C ++ (то есть не специфично для Microsoft)? Считается ли его использование хорошей практикой? И как называется этот оператор?

Ответы [ 7 ]

16 голосов
/ 14 июля 2009

Оператор вставки токена , используемый препроцессором для объединения двух токенов в один токен.

6 голосов
/ 14 июля 2009

Это также стандарт C ++, в отличие от того, что указано Raldolpho .

Вот соответствующая информация:

16.3.3 Оператор ## [cpp.concat]

1 A ## токен предварительной обработки не должен происходят в начале или в конце списка замены для любой формы макроопределения.

2 Если в список замены, параметр непосредственно предшествует или сопровождается ## токен предварительной обработки, параметр заменен на соответствующий маркер предварительной обработки аргумента последовательность.

3 как для объектоподобных, так и для функциональные вызовы макросов, до замены списка пересмотрены для большего количества имен макросов заменить каждый экземпляр ## токен предварительной обработки при замене список (не из аргумента) удаляется и предыдущий токен предварительной обработки связан со следующим токен предварительной обработки. Если результат не действительный токен предварительной обработки, поведение не определено. Результирующий токен доступен для дальнейшего макроса замена. Порядок оценки из ## операторов не указано.

5 голосов
/ 14 июля 2009

Это оператор предварительной обработки, который объединяет левый и правый операнды (без вставки пробела). Я не думаю, что это специфично для Microsoft.

3 голосов
/ 14 июля 2009

Это не стандартный C ++, это стандартный C. Проверьте эту статью в Википедии .

И это хорошая практика? В общем, я ненавижу макросы препроцессора и думаю, что они такие же плохие, как (если не хуже) Goto.

Редактировать: Очевидно, меня неправильно поняли, что я имел в виду под "Это не Стандарт С ++, это Стандарт С". Многие люди читают первую фразу и не могут прочитать вторую. Я хочу указать, что макросы были унаследованы C ++ от C.

2 голосов
/ 14 июля 2009

Это оператор вставки токена, разрешенный стандартом C ++ (подробности см. В 16.3.3). Что касается хорошей практики: использование макросов не является хорошей практикой ИМХО (в C ++).

2 голосов
/ 14 июля 2009

Как сказал Мердад, он объединяет операнды, например:

#define MyMacro(A,B) A ## B
MyMacro(XYZ, 123) // Equivalent to XYZ123

Обратите внимание, что MISRA C предлагает не использовать этот операнд (и операнд # 'stringify') из-за порядка вычисления, зависящего от компилятора.

1 голос
/ 14 июля 2009

это конкатенация для аргументов макроса, т.е.

GET_ACCESSOR (int, Age);

будет израсходовано до

inline int GetAge()  { DXUTLock l; return m_state.m_Age;};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...