Объединение строковых литералов и целочисленных констант - PullRequest
3 голосов
/ 05 октября 2010

Учитывая целое число времени компиляции (объект, а не макрос), могу ли я объединить его со строковым литералом во время компиляции, возможно с препроцессором?

Например, я могу объединять строковые литералы, просто помещая их рядом друг с другом:

bool do_stuff(std::string s);
//...
do_stuff("This error code is ridiculously long so I am going to split it onto "
         "two lines!");

Отлично! Но что, если я добавлю целые константы в смесь:

const unsigned int BAD_EOF = 1;
const unsigned int BAD_FORMAT = 2;
const unsigned int FILE_END = 3;

Можно ли использовать препроцессор, чтобы каким-то образом связать это со строковыми литералами?

do_stuff("My error code is #" BAD_EOF "! I encountered an unexpected EOF!\n"
         "This error code is ridiculously long so I am going to split it onto "
         "three lines!");

Если это невозможно, могу ли я смешивать константные строки со строковыми литералами? То есть если бы мои коды ошибок были строками, а не беззнаками?

И если ни то, ни другое невозможно, каков самый короткий и чистый способ соединить это сочетание строковых литералов и числовых кодов ошибок?

Ответы [ 2 ]

9 голосов
/ 05 октября 2010

Если бы BAD_EOF был макросом, вы могли бы stringize it:

#define STRINGIZE_DETAIL_(v) #v
#define STRINGIZE(v) STRINGIZE_DETAIL_(v)

"My error code is #" STRINGIZE(BAD_EOF) "!"

Но это не так (и это всегда хорошо), поэтому вам нужно format string :

stringf("My error code is #%d!", BAD_EOF)

stringstream ss; ss << "My error code is #" << BAD_EOF << "!";
ss.str()

Если это вас очень беспокоит (не должно быть, определенно не поначалу), используйтеотдельная специализированная строка для каждой константы:

unsigned const BAD_EOF = 1;
#define BAD_EOF_STR "1"

У этого есть все недостатки макроса плюс еще накрутка , обеспечивающая незначительную производительность, которая, вероятно, победилНе имеет значения для большинства приложений.Однако, если вы решите этот компромисс, это должен быть макрос, потому что препроцессор не может получить доступ к значениям , , даже если они постоянны.

0 голосов
/ 05 октября 2010

Что не так с:

do_stuff(my_int_1,
     my_int_2,
     "My error code is #1 ! I encountered an unexpected EOF!\n"
     "This error code is ridiculously long so I am going to split it onto "
     "three lines!");

Если вы хотите абстрагировать коды ошибок, то вы можете сделать это:

#define BAD_EOF "1"

Тогда вы можете использовать BAD_EOF, как если бы это был строковый литерал.

...