我有一个宏,它创建一个类
Info
的实例,该类接受具有模板化大小的数组作为构造函数参数。尺寸信息用于检查。
我想在返回实例之前检查这个宏。支票可能类似于
static_assert
,但我们将其保留在此处。进行检查的一种优雅方法是让宏调用执行检查的 lambda,然后返回实例。
但是由于一个非常烦人的原因而失败:如果我将 char 数组传递给 lambda 的
auto
参数,它们将被推导为 char
指针,这会阻止调用 Info
构造函数。所以我想将具有模板化大小的 char 数组传递给 lambda。但这只有从 C++20 开始才有可能。
有什么解决办法吗?我可以使用 C++ 17 让 lambda 接受模板化大小的数组吗?
代码:
#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;
}
编译器资源管理器中的示例:https://godbolt.org/z/8q5zYKj4a
只需删除模板部分并通过
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__)
仅当您转换为值时才会发生衰减到指针(包括裸
auto
)。上面的 function
的类型将是一些对数组的引用(与 file
相同)。