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
если я не могу их использовать?
1 ответ
Как указал Джастин, проблема с вашим кодом заключается в том, что аргумент функции не является constexpr, а проблема использования source_location в функции constexpr более полезным образом упоминается в constexpr! предложение функций, которое гласит:
TS "Library Fundamentals 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, а не там, где оно определено.
Однако непосредственные функции (то есть 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. }
Так что это в настоящее время открытая проблема.