std :: экспериментальный :: source_location во время компиляции - PullRequest
0 голосов
/ 24 октября 2018

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, если я не могу их использовать?

1 Ответ

0 голосов
/ 25 октября 2018

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

TS "Основы библиотеки v. 2" содержит "волшебный" класс source_location, который получает информацию, аналогичную FILE и Макросы LINE и переменная 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 вместо того, где оно определено.

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

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

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

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

...