Я работаю над проектом, в котором много константных строк, образованных конкатенацией (числа и т. Д.).
Например, у меня есть макрос LOCATION
, который форматирует __FILE__
и __LINE__
в строку, которую я могу использовать, чтобы узнать, где я нахожусь в коде, при печати сообщений или ошибок:
#define _STR(x) # x
#define STR(x) _STR(x)
#define LOCATION __FILE__ "(" STR(__LINE__) ")"
Таким образом, это будет форматировать местоположение как "file.cpp (42)". Проблема в том, когда я пытаюсь преобразовать результат в широкую строку:
#define _WIDEN(x) L ## x
#define WIDEN(x) _WIDEN(x)
#define WLOCATION WIDEN(LOCATION)
Это прекрасно работает с GCC, и в моем коде вставляется L "file.cpp (42)". Тем не менее, при попытке это с MSVC ++ (с использованием Visual C ++ 2008 Express), я получаю сообщение об ошибке:
error: Concatenating wide "file.cpp" with narrow "("
Я понимаю, что префикс L
добавляется только к первому члену в моем выражении. Я также попробовал это:
#define _WIDEN(x) L ## #x
Который "работает", но дает строку L"\"file.cpp\" \"(\" \"42\" \")\""
, что, очевидно, не очень удобно (и не то, что я ищу), особенно если учесть, что этот макрос прост по сравнению с другими макросами.
Итак, мой вопрос: как я могу применить его ко всему выражению в MSVC ++, чтобы я мог получить тот же результат, что и с GCC? Я бы предпочел не создавать вторую строку с токенами общего назначения, потому что тогда мне пришлось бы поддерживать два макроса для каждого, что не очень удобно и может привести к ошибкам. Кроме того, мне также нужна узкая версия каждой строки, поэтому, к сожалению, использование широких строк тоже не вариант.