std::source_location în C++

Informații despre locul din cod (fișier, funcție, linie) unde este apelată o funcție; înlocuiește __LINE__.

Sintaxă
#include <source_location>
static consteval source_location current() noexcept;
const char* file_name();  const char* function_name();
std::uint_least32_t line();  std::uint_least32_t column();

Ce face std::source_location

std::source_location::current() returnează un obiect cu numele fișierului, funcția, linia și coloana unde este scris apelul. Înlocuiește macro-urile vechi __FILE__, __LINE__ și __func__.

Trucul util: pus ca argument implicit al unei funcții (std::source_location loc = std::source_location::current()), primește locul de unde este apelată funcția, nu locul unde este definită. Așa se scriu funcții de jurnal care arată automat de unde vin mesajele.

Textul exact din function_name() depinde de compilator (clang afișează semnătura completă). file_name() este calea dată compilatorului, de obicei absolută, de aceea exemplele afișează doar numele fișierului.

Ce returnează

Un obiect std::source_location.

Exemple

Exemplul 1: O funcție de jurnal care știe de unde este apelată

#include <filesystem>
#include <print>
#include <source_location>
#include <string_view>

void jurnal(std::string_view mesaj, std::source_location loc = std::source_location::current()) {
    std::println("[{}:{}] {}: {}",
                 std::filesystem::path(loc.file_name()).filename().string(),
                 loc.line(), loc.function_name(), mesaj);
}

void conecteaza() {
    jurnal("conectare la server");
}

int main() {
    jurnal("program pornit");
    conecteaza();
}

Rezultat

[exemplu.cpp:17] int main(): program pornit
[exemplu.cpp:13] void conecteaza(): conectare la server

Exemplul 2: Linie și coloană

#include <print>
#include <source_location>

int main() {
    auto loc = std::source_location::current();
    std::println("linia {}, coloana {}", loc.line(), loc.column());
}

Rezultat

linia 5, coloana 16

Greșeli frecvente

  • Apelezi std::source_location::current() în corpul funcției de jurnal. Primești mereu linia din funcția de jurnal; trebuie pus ca argument implicit, ca să fie evaluat la locul apelului.

Comenzi înrudite

  • assert: Verifică o condiție care trebuie să fie mereu adevărată; dacă e falsă, oprește programul cu un mesaj.
  • #define: Definește un macro: preprocesorul înlocuiește textual numele cu valoarea lui, peste tot în cod, înainte de compilare.
  • std::exception: Clasa de bază a tuturor excepțiilor din biblioteca standard; what() returnează mesajul erorii.