2013-10-13 3 views
31

Я хочу, чтобы мои сообщения об исключениях содержали информацию об исключении.C++ конкатенация __FILE__ и __LINE__ макросов?

Так что я хотел бы иметь что-то подобное.

#define LOCATION __FILE__ " : " __LINE__ 

throw std::exception(std::string("ABCD. ") + LOCATION); 

Это определение явно неверно. Как достичь этого?

+1

Примечание. Вы можете упростить построение исключения до 'std :: exception (" ABCD. "LOCATION)'. –

+0

вы можете посмотреть здесь http://stackoverflow.com/questions/1739102/concatenating-strings-in-macros-c –

ответ

50

Вам нужно расширить этот макрос в двух уровнях:

#define S1(x) #x 
#define S2(x) S1(x) 
#define LOCATION __FILE__ " : " S2(__LINE__) 

Почему?

Короткий ответ: Вам нужно расширить __LINE__ в двух уровнях, прежде чем передать его в #x.

Длинный ответ: Прежде всего, с помощью оператора # в функции, как макроса, он должен сопровождаться макро параметром, но __LINE__ не является параметр, поэтому компилятор жалуется на это бродячий оператор.

Во-вторых, сама по себе __LINE__ макрос и содержит номер текущей строки, она должна быть расширена на номер, прежде чем использовать его с #, в противном случае, вы получите строку "__LINE__" вместо номера.

Macro S2(__LINE__) расширяет __LINE__ до номера строки, затем мы передаем номер строки #x.

+2

Что делать, если я хочу добавить __PRETTY_FUNCTION__ в качестве третьего? Заранее спасибо! – sree

+3

Boost's ['BOOST_PP_STRINGIZE (__LINE__)'] (http://www.boost.org/doc/libs/1_49_0/libs/preprocessor/doc/ref/stringize.html) делает это, если вы не хотите создайте свои собственные макросы S1 и S2. – AndiDog

+1

@sree: #define LOCATION std :: string (__ PRETTY_FUNCTION__) + "::" + std :: string (__ FILE__) + ":" + std :: string (S2 (__ LINE__)) – adiog

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