Нельзя использовать не, или, или плюс в качестве идентификатора?

Я попытался скомпилировать это:

enum class conditional_operator { plus, or, not };

Но, по-видимому, GCC (4.6) считает их особенными, хотя я не могу найти стандарт, в котором говорится, что это так (ни C++0x n3290, ни C99 n2794). Я компилирую с помощью g++ -pedantic -std=c++0x. Это удобство компилятора? Как отключить? Не следует ли -std=c++0x отключить эту "функцию"?

PS: Хммм, видимо, форматирование кода MarkDown тоже так думает...


person rubenvb    schedule 06.06.2011    source источник
comment
Забавно, как код правильно окрашивает or и not как зарезервированные, но отделяет plus :) Лично я бы предпочел отказаться от использования || и && в пользу or и and (соответственно), гораздо меньше путаницы с побитовыми операторами.   -  person Matthieu M.    schedule 06.06.2011
comment
у моего коллеги есть код в работах, который использует or и and в качестве имен функций-членов. Я с нетерпением жду, когда он попробует и громко заплачет.   -  person Johannes Schaub - litb    schedule 06.06.2011


Ответы (5)


Смотри 2.5. Это альтернативные токены для || и !.

Кстати, есть куча других альтернативных токенов.

Изменить: причина их включения такая же, как и у триграфов: разрешить использование наборов символов, отличных от ASCII. Комитет пытался избавиться от них (по крайней мере, от триграфов, я не помню альтернативных токенов) и встретил сопротивление людей (в основном пользователей мейнфреймов IBM), которые их используют.

Отредактируйте для полноты: поскольку другие сделали замечания, плюс не входит в этот класс и не должен быть проблемой, если вы не using namespace std.

person AProgrammer    schedule 06.06.2011
comment
+1 для стандартного раздела, хотя ссылка @Jon уже позволила мне его найти. - person rubenvb; 06.06.2011

На самом деле они определены как альтернативные токены (и зарезервированы), как ни странно, как альтернативные представления для операторов. Я полагаю, что изначально это было сделано для того, чтобы помочь людям, которые использовали клавиатуры, которые затрудняли создание соответствующих символов, хотя это кажется довольно плохой причиной для добавления дополнительных ключевых слов в язык :(

может компилятор GCC отключает их, но я не уверен.

(Как упоминалось в комментариях, plus должно быть хорошо, если вы не используете пространство имен std.)

person Jon Skeet    schedule 06.06.2011
comment
Технически они не являются ключевыми словами (в препроцессоре эффект другой). - person AProgrammer; 06.06.2011
comment
@AProgrammer: А, я просто просматривал страницу, на которую ссылался. Является ли ваш термин (альтернативные токены) лучшим для использования? Я предполагаю, что они все еще зарезервированы так же, как и ключевые слова? - person Jon Skeet; 06.06.2011
comment
Это заголовок раздела 2.5 и таблицы 2. - person AProgrammer; 06.06.2011

or и not являются альтернативными представлениями || и ! соответственно. Вы не можете отключить их, и вы не можете использовать эти токены ни для чего другого, они являются частью языка (текущий C++, даже не просто C++0x). (См. ISO/IEC 14882:2003 2.5 [lex.digraph] и 2.11 [lex.key]/2.)

Вы должны быть в безопасности с plus, если только вы не используете using namespace std; или using std::plus;.

person CB Bailey    schedule 06.06.2011
comment
+1 за то, что первым указал, что plus должен быть в безопасности. - person rubenvb; 06.06.2011

Стандарт перечисляет ключевые слова в 2.11. Существует также список альтернативных представлений, отдельный от списка ключевых слов, который зарезервирован и не может использоваться иначе, но не является ключевым словом. and и or находятся в этом списке. Раздел 17.4.3 описывает ограничения для программ, использующих библиотеки, а 17.4.3.1.3 описывает, что имена, объявленные с внешней ссылкой в ​​заголовке, зарезервированы как в std::, так и в глобальном пространстве имен.

Другими словами, вам не нужно переходить на C++0x, чтобы иметь эти проблемы. and и or уже зарезервированы, а заголовок <functional> содержит plus в качестве шаблонного типа структуры, и поэтому plus является недопустимым, если <functional> прямо или косвенно является #included.

Я не уверен, что сбрасывать столько всего в глобальное пространство имен было действительно разумно, но так говорит стандарт.

person David Thornley    schedule 06.06.2011
comment
Ничего себе, альтернативная таблица представления была на следующей странице :s. Я также не знал о проблеме plus. Думаю, мне придется прибегнуть к plus_op, or_op и not_op... - person rubenvb; 06.06.2011
comment
Я думаю, что сказать, что plus нельзя, это немного сильно. Он надежно встроен в пространство имен std. - person CB Bailey; 06.06.2011
comment
@Charles Bailey: 17.4.3.1.3/1: Каждое имя, объявленное как объект с внешней связью в заголовке, зарезервировано для реализации для обозначения этой библиотеки с внешней связью как в пространстве имен std, так и в глобальном пространстве имен. Мне это тоже кажется странным. - person David Thornley; 06.06.2011
comment
Но шаблон класса не является объектом. Я думаю, вы неверно истолковали этот раздел. Это относится к таким вещам, как cout, cerr, clog, cin, errno, а не к классам и шаблонам. Я не могу думать ни о каких других, но я уверен, что есть и другие. - person CB Bailey; 06.06.2011

Это поправка 1995 года к стандарту C90. Вероятно, компилятор может выбрать, как вести себя в этом случае. GCC, вероятно, включает заголовок как часть стандартной библиотеки. С Microsoft это не так, и вы должны включить iso646.h.

Вот ссылка на википедию по этому поводу.

person Marino Šimić    schedule 06.06.2011
comment
Однако этот вопрос касается C++. - person CB Bailey; 06.06.2011
comment
@Charles: но на самом деле это причина, по которой он находится в стандарте C ++, потому что изначально он был на C (если я правильно понимаю, я ошибался раньше ...) - person rubenvb; 06.06.2011
comment
в вики есть раздел, посвященный C++. - person Marino Šimić; 06.06.2011