2013-02-12 6 views
1

Я хочу определить кучу констант в выделенном файле заголовка.Как конкатенировать строки в заголовке?

Поскольку некоторые префиксы встречаются довольно часто, я хочу их определить один раз, а затем добавить их всякий раз, когда это необходимо.

Мой вопрос:

Как я могу сцепить префикс с другой строкой без пространства?

Пример:

#define PREFIX "pre_" 
#define KEYWORD "keyword" 
#define BOTH PREFIX+KEYWORD 

Желаемый результат для ОБА: pre_keyword

очевидно + в

BOTH PREFIX+KEYWORD 

не будет работать. Итак, как эти маркеры могут быть конкатенированы?

+0

http://gcc.gnu.org/onlinedocs/cpp/Concatenation.html – fritzone

+0

'##' выполняет конкатенацию. –

+2

@AlokSave нет в этом случае. – Pubby

ответ

6

Просто

#define BOTH PREFIX KEYWORD 

бы это сделать.

Прилегающие литералы автоматически сцепляются, так

"pre_" "keyword" 

станет

"pre_keyword" 
+0

Я использую эти константы в качестве ключей на карте . Он отлично работает для простых констант, но не для конкатенированных строк! – bogus

+0

@bogus, тогда вы делаете это неправильно. Вы даже не должны использовать макрос для этого, и макросы расширяются до запуска программы, поэтому, даже если вы используете макросы, вы просто запутываете код. –

+0

Хорошо, какой подход вы бы предложили? Определить константы в cpp как обычные строки? – bogus

1

Если вы хотите придерживаться макросов, это краткое объяснение того, что происходит и как она может быть улучшена ,

#define PREFIX "pre_" 
#define KEYWORD "keyword" 

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

#define BOTH PREFIX+KEYWORD 

затем будет заменен

"pre_"+"keyword" 

приводит к указателю того, явно не то, что вы хотите. Как и в C и C++, мы можем разделить C-строки, просто написав части рядом друг с другом без какого-либо оператора (они будут обрабатываться как один C-string литерал, а не конкатенация две C-строки):

"pre_" "keyword" 

Так что вы хотите макрос быть

#define BOTH PREFIX KEYWORD 

Если такие префиксы будут использоваться довольно часто в вашей программе, я лучше рекомендовать следующий метод:

#define PRE(x) "pre_" x 

и "вызвать" макрос с

PRE("keyword") 

, которая будет расширяться до "pre_" "keyword".

Теперь, если "keyword" всегда будет время компиляции C-строка, которая может быть записана как лексем (без специальных символов), вы можете даже заставить его работать без кавычек:

#define PRE(x) "pre_" #x 

#x будет «конвертировать» токен x в литерал C-строки. Затем, вы можете написать следующее:

PRE(keyword) 

Обратите внимание, что это делается с помощью предварительной обработки, так keyword может даже быть ключевым словом C/C++, и она будет иметь силу, как PRE(if).

Для полноты: Если вы хотите, чтобы результат еще маркер, вы можете выполнить конкатенацию лексем с помощью оператора препроцессоре ##:

#define PRE(x) pre_ ## x 

Затем PRE(keyword) будет расширяться pre_keyword.

+0

+/- 0 ;-). Хорошее объяснение конкатенации, но «я скорее рекомендую следующее», сомнительно, и ключевое слово PRE опасно противоречит интуиции ... кто-то говорит, что PRE (x) может ожидать, что он будет использовать локальную переменную «x» каким-то образом. –

+0

'PRE (x)' всегда следует читать как макрос. У вас всегда есть проблема, что, глядя только на код использования макроса, вы не знаете, что происходит. Но при написании всех макросов в верхнем регистре вы SHOUT читаете код: 'I_AM_DANGEROUS_SO_HAVE_A_LOOK_WHAT_I_AM_DOING';) ** Никогда ** не пишите' pre (x) ', хотя в этом случае я полностью согласен с вами. Например, если вы пишете синтаксический анализатор и имеете токен типа 'if',' else' и т. Д., Вы хотите сохранить их в 'parser_token_if' и т. Д., Чтобы вы могли написать' TOK (if) 'expand to' parser_token_if'. И, конечно, сохраните определение макроса как можно более локальным. – leemes

+1

Мне не очень нравится использование макроса стиля функции. Я не вижу никаких проблем с тем, как он изначально хотел это сделать. –

Смежные вопросы