Как можно реализовать std :: эксперимент :: источник-расположение?

Расширения C ++ для основ библиотеки, версия 2 (N4564) вводит тип std::experimental::source_location.

§ 14.1.2 [refle.src_loc.creation] говорит:

static constexpr source_location current() noexcept;

Возвращает: Когда вызывается вызовом функции (C ++ 14 §5.2.2), чей постфикс-выражение является (возможно, в скобках) ID-выражение именование current, возвращает source_location с определенным значением реализации. Значение должно зависеть от #line (C ++ 14 §16.4) таким же образом, как для __LINE__ а также __FILE__, Если вызывается каким-либо другим способом, возвращаемое значение не указано.

Примечания: Когда скобки или равно-инициализатор используется для инициализации нестатического члена данных, любых вызовов current должно соответствовать расположению конструктора или агрегатной инициализации, которая инициализирует член.

[ Замечания: При использовании в качестве аргумента по умолчанию (C ++ 14 §8.3.6), значение source_location будет место вызова current на сайте вызова. — конечная нота ]

Если я правильно понимаю, то эта функция предназначена для использования таким образом.

#include <experimental/source_location>  // I don't actually have this header
#include <iostream>
#include <string>
#include <utility>

struct my_exception
{

std::string message {};
std::experimental::source_location location {};

my_exception(std::string msg,
std::experimental::source_location loc = std::experimental::source_location::current()) :
message {std::move(msg)},
location {std::move(loc)}
{
}

};

int
do_stuff(const int a, const int b)
{
if (a > b)
throw my_exception {"a > b"};  // line 25 of file main.cxx
return b - a;
}

int
main()
{
try
{
std::cout << do_stuff(2, 1) << "\n";
}
catch (const my_exception& e)
{
std::cerr << e.location.file_name() << ":" << e.location.line() << ": "<< "error: " << e.message << "\n";
}
}

Ожидаемый результат:

main.cxx:25: error: a > b

Без std::experimental::source_locationмы могли бы использовать вспомогательный макрос THROW_WITH_SOURCE_LOCATION что внутренне использует __FILE__ а также __LINE__ макросы для правильной инициализации объекта исключения.

Мне было интересно, как библиотека может реализовать std::experimental::source_location, Если я не совсем упущен, это невозможно без специальной поддержки компилятора. Но какие магические функции компилятора понадобятся для этой работы? Будет ли это сопоставимо с трюком, развернутым для std::initializer_list? Есть ли экспериментальная реализация этой функции, которую можно посмотреть? я проверил источники SVN для GCC но пока ничего не нашел.

6

Решение

Реализация этого потребует поддержки от компилятора. Например, с gcc, вы могли бы использовать встроенные функции лайк

   int __builtin_LINE()

Эта функция эквивалентна препроцессору __LINE__ макрос и возвращает номер строки вызова встроенного. В C ++ аргумент по умолчанию для функции F, он получает номер строки вызова F,

   const char * __builtin_FUNCTION()

Эта функция эквивалентна препроцессору __FUNCTION__ макрос и возвращает имя функции, в которой находится вызов встроенной функции.

   const char * __builtin_FILE()

Эта функция эквивалентна препроцессору __FILE__ макрос и возвращает имя файла, в котором находится вызов встроенного. В аргументе C ++ по умолчанию для функции F, он получает имя файла вызова F,

7

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]