std :: экспериментальный :: source_location во время компиляции

std::experimental::source_location вероятно, будет добавлен в стандарт C ++ в какой-то момент. Мне интересно, возможно ли получить информацию о местоположении в области времени компиляции. По сути, я хочу функцию, которая возвращает разные типы при вызове из разных источников. Примерно так, хотя он не компилируется, потому что location объект не constexpr так как это аргумент функции:

#include <experimental/source_location>

using namespace std::experimental;

constexpr auto line (const source_location& location = source_location::current())
{
return std::integral_constant<int, location.line()>{};
}

int main()
{
constexpr auto ll = line();
std::cout << ll.value << '\n';
}

Это не компилируется, с сообщением о

expansion of [...] is not a constant expression

учитывая return std::integral_constant<int, location.line()>{} линия. Как хорошо иметь методы source_location быть constexpr если я не могу их использовать?

3

Решение

Как указал Джастин, проблема с вашим кодом заключается в том, что аргумент функции не является constexpr, но проблема использования source_location в функции constexpr более полезным образом упоминается в constexpr! функции предложение, в котором говорится:

TS «Основы библиотеки v. 2» содержит «волшебное» source_location
класс добраться до информации, аналогичной ФАЙЛ а также ЛИНИЯ макрос
и FUNC переменная (см. N4529 для текущего проекта и N4129
для некоторых дизайнерских заметок). К сожалению, потому что «ценность»
source_location заморожен в точке source_location :: current ()
Вызывается, составление кода с использованием этого магического класса сложно:
Как правило, функция, желающая отследить свою точку вызова, должна
добавить параметр по умолчанию следующим образом:

void my_log_function(char const *msg,
source_location src_loc
= source_location::current()) {
// ...
}

Эта идиома гарантирует, что значение source_location :: current ()
Вызывается выборка, где вызывается my_log_function, а не где
это определено.

Немедленные (то есть, constexpr!) Функции, однако, создают чистую
разделение между процессом компиляции и constexpr
процесс оценки (см. также P0992). Таким образом, мы можем сделать
source_location :: current () непосредственная функция, и оберните ее как
необходимо в других непосредственных функциях: произведенная стоимость будет
соответствуют исходному расположению «корневой» непосредственной функции
вызов. Например:

constexpr! src_line() {
return source_location::current().line();
}

void some_code() {
std::cout << src_line() << '\n';  // This line number is output.
}

Так что это в настоящее время открытая проблема.

5

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

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