I have a macro that creates an instance of a class Info
that accepts arrays with templated size as constructor arguments. The size information is used for checks.
I would like to do a check in this macro before returning the instance. The check could be something like a static_assert
, but let's leave that open here. An elegant way to do the check is to make the macro call a lambda that performs the check(s) and then returns the instance.
But this fails because of a very annoying reason: if I pass char arrays to an auto
argument of the lambda, they are deduced as char
pointers and this prevents calling the Info
constructor. So I would like to pass char arrays with templated size to the lambda. But this is only possible from C++20 on.
Is there any workaround? Can I make a lambda accept arrays of templated size with C++ 17?
Code:
#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;
}
Example in Compiler Explorer: https://godbolt.org/z/8q5zYKj4a
Simply delete the template parts and take the variables by const&
:
[](const auto&function, const auto&file) \
{ \
static constexpr char error_string[] = "invalid"; \
if ('m' != function[0]) { \
return Info(error_string, error_string); \
} \
return Info(function, file); \
}(__FUNCTION__, __FILE__)
decay-to-pointer only happens if you convert to a value (bare auto
include). The type of function
in the above will be some reference-to-array (and same for file
).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With