Какова цель ## оператора в C++, и чем это называют?

У меня есть различные дополнительные методы в моем проект MiscUtil (полный источник доступен там - я не собираюсь повторять его здесь). Мои фавориты, некоторые из которых включают другие классы (такие как диапазоны):

материал Даты и времени - главным образом для модульных тестов. Не уверенный я использовал бы их в производстве:)

var birthday = 19.June(1976);
var workingDay = 7.Hours() + 30.Minutes();

Диапазоны и ступающий - крупный благодаря Marc Gravell для его материал оператора для создания это возможным:

var evenNaturals = 2.To(int.MaxValue).Step(2);
var daysSinceBirth = birthday.To(DateTime.Today).Step(1.Days());

Сравнения:

var myComparer = ProjectionComparer.Create(Person p => p.Name);
var next = myComparer.ThenBy(p => p.Age);
var reversed = myComparer.Reverse();

Проверка аргументов:

x.ThrowIfNull("x");

LINQ к XML относился к анонимным типам (или другим типам с соответствующими свойствами):

// Jon32
new { Name="Jon", Age=32}.ToXElements();
// Name="Jon" Age="32" (as XAttributes, obviously)
new { Name="Jon", Age=32}.ToXAttributes()

Нажатие LINQ - занял бы слишком много времени объяснять здесь, но искать его.

5
задан Dima 13 July 2009 в 20:55
поделиться

7 ответов

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

16
ответ дан 18 December 2019 в 05:29
поделиться

Это также стандартный C ++, вопреки утверждениям Ралдольфо .

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

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

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

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

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

6
ответ дан 18 December 2019 в 05:29
поделиться

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

5
ответ дан 18 December 2019 в 05:29
поделиться

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

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

Изменить: По-видимому, меня неправильно понимают, говоря о том, что я имел в виду, говоря «Это не стандартный C ++, это стандартный C». Многие люди читают первую фразу и не читают вторую. Я намерен указать, что макросы были унаследованы C ++ от C.

3
ответ дан 18 December 2019 в 05:29
поделиться

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

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

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

2
ответ дан 18 December 2019 в 05:29
поделиться

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

2
ответ дан 18 December 2019 в 05:29
поделиться

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

GET_ACCESSOR (int, Age);

будет преобразовано в

inline int GetAge()  { DXUTLock l; return m_state.m_Age;};
1
ответ дан 18 December 2019 в 05:29
поделиться