Функция вывода __LINE__
{
cout << file << endl;
cout << line << endl;
}
#define PRINT_FILE_AND_LINE() PrintFileAndLine(__LINE__, __FILE__)
int main()
{
PRINT_FILE_AND_LINE();
return 0;
}
Тут есть пара недостатков - макрос должен как-бы знать имя функции, поэтому необходимо обеспечить то, что он будет объявлен после функции. Кроме того, нельзя перенести функцию, занести ее в класс и т.п.
Второй способ:
void PrintFileAndLine(const int line = 0, const char* file = "")
{
cout << file << endl;
cout << line << endl;
}
int main()
{
LF(PrintFileAndLine);
return 0;
}
Вроде бы он решает перечисленные выше проблемы. Однако, синтаксис получается непонятный.
Есть ли еще какие-то варианты? В идеале, хотелось бы чтобы не было дополнительных макросов (кроме __LINE__, __FILE__).
Я не C++ник, но тупой запрос в МСДН выдал
__FUNCTION__ и __FUNCDNAME__ для декорированного имени функции, а также __FUNCSIG__ для сигнатруры.
З.Ы. В Nemerle тоже самое можно вообще своими руками сделать.
__FUNCTION__ и __FUNCDNAME__ для декорированного имени функции, а также __FUNCSIG__ для сигнатруры.
1. Это имеет только косвенное отношение к C++. Все-таки макросы - это наследие C. Соответственно, я их стараюсь не применять. Но тут видно не обойтись без них.
2. МСДН в данном случае не указ (каким был бы, если бы я искал описание функций Win32 API). Данных макросов в стандартах я не нашел (в отличие от __LINE__), да и компилятор мой только __FUNCTION__ переварил.
3. Однако, я так и не понял, как данный макрос мне поможет в выводе номера текущей строки.
void PrintFileAndLine(const int line, const char* file = "")
{
cout << file << endl;
cout << line << endl;
}
int main()
{
PRINT_FILE_AND_LINE();
return 0;
}
Да и кто сказал что это обязательно должна быть ф-ция, функциональных объектов никто не отменял.
struct
{
void operator()(const int line, const char* file = "")
{
cout << file << endl;
cout << line << endl;
}
} PrintFileAndLine;
int main()
{
PRINT_FILE_AND_LINE();
return 0;
}
А если еще беспокоит глобальность сего то static и namespace в помощь.
PS: Требуемая универсальность слишком универсальна ибо реальная потребность ограничивается малым.
Насколько я понимаю, static и namespace от глобальности макроса не спасут. А это меня больше всего беспокоит.
Возможно. Я изучаю модуль MiniCppUnit, который применяется для тестирования. В нем весь интерфейс сделан с помощью подобных макросов, с помощью чего модуль может выводить информацию о месторасположении непрошедшего теста. Надеялся придумать альтернативу макросам, как-то их замаскировать. Думал, может шаблоны или что-то типа inline поможет, но не вышло.
Насколько я понимаю, static и namespace от глобальности макроса не спасут. А это меня больше всего беспокоит.
[/QUOTE]
Зато спасут от торчаших наружу символов. А локальность макроса обеспечивается независимым инклудом.
Возможно, я беспокоюсь по пустякам. Но надо же было произвести небольшое исследование - вдруг бы нашел красивую альтернативу.
Однако, альтернативу вижу одну - просто не пользоваться этими макросами, журтвуя преимуществами, которые они дают.