Considere o seguinte código:
void Log(std::string_view msg,
std::source_location const& loc = std::source_location::current()) {
// Performance penalty!
auto const n = std::strlen(loc.file_name());
auto s = ""s;
s.resize(msg.size() + n);
std::memcpy(&s[0], msg.data(), msg.size());
std::memcpy(&s[msg.size()], loc.file_name(), n);
s[msg.size() + n] = 0; // ensure to be null-terminated
// sendToRemoteMachine(s);
}
Obviamente, se std::source_location::file_name
retornar a std::string_view
, a penalidade de desempenho pode ser facilmente evitada.
Eu acho que std::source_location::file_name
é uma informação gerada em tempo de compilação e somente leitura. O compilador pode armazená-lo em um std::string_view
objeto.
Por que não std::source_location
fornece comprimentos para evitar penalidades de desempenho em C++20?
Atualizar
Outro artigo relacionado: std::source_location
está quebrado
C++ não possui um tipo que represente todos os itens a seguir:
std::string
tem 2 e 3, mas não 1.string_view
tem 1 e 2, mas não garante 3 no nível do tipo.char const*
tem 1 e há uma expectativa geral de que usem 3, mas não carreguem 2.E sim, o número 3 é realmente muito importante. Seu exemplo deseja passar a string para uma API que precisa de uma string dimensionada; é por isso que você está calculando o tamanho. Outras pessoas terão APIs que esperam um NTBS. Para eles, uma
string_view
API baseada em - agora exige que copiem a string dimensionada em um NTBS. Que é uma operação O(N).A menos que você tenha um tipo que comunique todos os três, um de vocês terá que fazer uma operação O(N).
Sim, tecnicamente,
string_view
poderia apontar para um NTBS. Mas no nível do tipo, se você receber umstring_view
, não saberá que ele aponta para um NTBS. Isso seria uma garantia da função que o gera, e não do tipo em si. Portanto seria um uso inadequado do tipo.Este artigo é sobre um problema amplamente separado: a falta de uma
constexpr
versão dosource_location
, que permitiria garantir que a string existisse apenas em tempo de compilação.Esse problema não é algo que qualquer construção de biblioteca possa resolver. Retornar
string_view
das funções-membro não resolveria o problema desse artigo. Emborastring_view
possa serconstexpr
, os parâmetros não podem. E comosource_location
é passado como parâmetro, deve seguir as regras da linguagem C++. Mesmo que o compilador o tenha gerado, é um parâmetro da função e, portanto, não pode ser umconstexpr
parâmetro.Na verdade, não poderia nem ser uma construção da linguagem C++ porque a linguagem não pode passar informações de tempo de compilação como parâmetro de função. Lembre-se: a fonte da informação é quem liga. O que o escritor desse artigo faria
__FILE__
seria inseri-lo manualmente em um parâmetro de modelo dessa função, não em um parâmetro de função.E deve-se observar: devolver um tamanho não é o problema descrito no artigo. Você pode calcular o tamanho de a
char const*
em tempo de compilação, se ochar const*
próprio forconstexpr
. Você pode então usar esse tamanho de tempo de compilação e elechar const*
mesmo para fabricar um tipo. O problema de que o artigo está falando está inteiramente no escopo de obter uma sequência de caracteres em tempo de compilação. Se é umstring_view
NTBSchar const*
ou umchar[N]
é irrelevante; qualquer um deles funcionaria.