consteval wrapper против source_location

Я попробовал следующий код, используя GCC10 в режиме C++20:

consteval std::experimental::source_location there()
{
   return std::experimental::source_location::current(); // Line 3
}

void f(const std::experimental::source_location& a = there()) // Line 6
{
   std::cout << a.line() << std::endl;
}

int main(int pArgc, char* pArgv[])
{
   std::cout << there().line() << std::endl; // Line 13
   f(); // Line 14

   return 0;
}

Я ожидал следующего результата:

13
14

но я получил:

3
3

Тогда я попробовал такой вариант:

consteval std::experimental::source_location there(const std::experimental::source_location& a = std::experimental::source_location::current())
{
   return a; // Line 3
}

void f(const std::experimental::source_location& a = there()) // Line 6
{
   std::cout << a.line() << std::endl;
}

Я ожидал следующего результата:

13
14

но я получил:

13
6

Почему код так себя ведет? Есть ли способ заставить его вести себя так, как ожидалось, без использования макроса препроцессора?

2 ответа

source_location::current() всегда дает вам точное местоположение, откуда он вызван. Наблюдаемое поведение - именно то, как оно должно работать.

Аргументы функции по умолчанию оцениваются на сайте вызова. Вот почему первый вызов во втором примере возвращает "13". Это также единственный способ использоватьsource_location когда он заключен в вызов функции (иначе это не имеет особого смысла).

Я оказался правильным второй вариант. На текущем GCC 12 все работает нормально.

Другие вопросы по тегам