Eu tenho uma macro que cria uma instância de uma classe Info
que aceita arrays com tamanho modelado como argumentos do construtor. As informações de tamanho são usadas para verificações.
Gostaria de fazer uma verificação nesta macro antes de retornar a instância. O cheque pode ser algo como static_assert
, mas vamos deixar isso aberto aqui. Uma maneira elegante de fazer a verificação é fazer com que a macro chame um lambda que execute a(s) verificação(ões) e depois retorne a instância.
Mas isso falha por um motivo muito chato: se eu passar arrays char para um auto
argumento do lambda, eles serão deduzidos como char
ponteiros e isso impedirá a chamada do Info
construtor. Então, eu gostaria de passar matrizes de caracteres com tamanho modelado para o lambda. Mas isso só é possível a partir do C++20.
Existe alguma solução alternativa? Posso fazer um lambda aceitar matrizes de tamanho modelado com C++ 17?
Código:
#include <cstdlib>
#include <iostream>
class Info
{
public:
template <size_t function_length, size_t file_length>
Info(const char (&function)[function_length], const char (&file)[file_length])
: function(function)
, file(file)
{
if ('\0' != function[function_length - 1])
{
this->function = "invalid";
}
if ('\0' != file[file_length - 1])
{
this->file = "invalid";
}
}
const char* function;
const char* file;
};
#define CREATE_INFO() \
( \
[]<std::size_t function_length, std::size_t file_length>( \
const auto(&function)[function_length], const auto(&file)[file_length]) \
{ \
static constexpr char error_string[] = "invalid"; \
\
if ('m' != function[0]) \
{ \
return Info(error_string, error_string); \
} \
return Info(function, file); \
}(__FUNCTION__, __FILE__))
int main()
{
Info info = CREATE_INFO();
std::cout << "Function: " << info.function << ", file: " << info.file << std::endl;
return 0;
}
Exemplo no Compiler Explorer: https://godbolt.org/z/8q5zYKj4a
Simplesmente exclua as partes do modelo e pegue as variáveis por
const&
:o decaimento para ponteiro só acontece se você converter para um valor (
auto
inclusão simples). O tipofunction
acima será alguma referência ao array (e o mesmo parafile
).