使宏为不存在的函数产生编译时错误
Make macro produce compile time error for non-existing function
我在命名空间中有几个函数。参数不同,对于每次调用,它们都会将包含字符串成员的对象存储到向量中。
命名空间中没有重载函数。
我想创建一个宏来生成 lambda 表达式,用于匹配通过调用某个函数创建的对象。除此之外,如果命名空间中不存在具有作为参数提供的名称的函数,宏还应该导致编译时错误。编译成功会影响结果吗? (如果可能的话,有和没有这个检查的编译结果将是相同的,而不依赖于可能会或可能不会根据优化级别优化的代码。)这可能吗?如果可能:我该如何实施?
我正在努力实现的示例;我要问的宏是 CALL_INFO_PREDICATE
; static_assert_function_exists
部分是任何可实现预期结果的代码的占位符:
struct CallInfo
{
const std::string m_function;
CallInfo(const std::string& function)
: m_function(function)
{
}
}
std::vector<CallInfo*> g_calledFunctions;
namespace mymath
{
// all functions with same return type, but differnent parameter lists
double sin(double radian)
{
g_calledFunctions.push_back(new CallInfo("sin"));
...
}
double atan2(double y, double x)
{
g_calledFunctions.push_back(new CallInfo("atan2"));
...
}
}
#define CALL_INFO_PREDICATE(functionName) [] (CallInfo* info) -> bool\
{\
static_assert_function_exists(mymath::functionName);/* << how to make this work? */\
return info->m_function == #functionName;\
}
int main ()
{
mymath::sin(1);
mymath::atan2(3, 7);
auto pos = std::find_if(g_calledFunctions.begin(), g_calledFunctions.end(), CALL_INFO_PREDICATE(sin)); // compiles; function sin exists in mymath
auto pos2 = std::find_if(g_calledFunctions.begin(), g_calledFunctions.end(), CALL_INFO_PREDICATE(cos)); // produces compile time error, since there is no function named cos in mymath
...
}
假设没有重载,您可以直接使用它:
#define CALL_INFO_PREDICATE(functionName) [] (CallInfo* info) -> bool \
{ \
static_cast<void>(&mymath::functionName); \
return info->m_function == #functionName; \
}
转换为 void
以避免对未使用的表达式发出警告。
为什么不将函数指针存储在 CallInfo
中并消除对宏的需要?
struct CallInfo
{
const std::string m_function;
void* m_function_ptr;
CallInfo(const std::string& function, void* function_ptr)
: m_function(function),
m_function_ptr(function_ptr)
{
}
}
std::vector<CallInfo*> g_calledFunctions;
namespace mymath
{
// all functions with same return type, but differnent parameter lists
double sin(double radian)
{
g_calledFunctions.push_back(new CallInfo("sin", sin));
...
}
double atan2(double y, double x)
{
g_calledFunctions.push_back(new CallInfo("atan2", atan2));
...
}
}
int main ()
{
mymath::sin(1);
mymath::atan2(3, 7);
auto pos = std::find_if(g_calledFunctions.begin(), g_calledFunctions.end(), [](CallInfo* info) { return info->m_function_ptr == &mymath::sin; });
auto pos2 = std::find_if(g_calledFunctions.begin(), g_calledFunctions.end(), [](CallInfo* info) { return info->m_function_ptr == &mymath::cos; });
// ...
}
现在编译器可以自动为您检查该函数是否存在。
我在命名空间中有几个函数。参数不同,对于每次调用,它们都会将包含字符串成员的对象存储到向量中。 命名空间中没有重载函数。
我想创建一个宏来生成 lambda 表达式,用于匹配通过调用某个函数创建的对象。除此之外,如果命名空间中不存在具有作为参数提供的名称的函数,宏还应该导致编译时错误。编译成功会影响结果吗? (如果可能的话,有和没有这个检查的编译结果将是相同的,而不依赖于可能会或可能不会根据优化级别优化的代码。)这可能吗?如果可能:我该如何实施?
我正在努力实现的示例;我要问的宏是 CALL_INFO_PREDICATE
; static_assert_function_exists
部分是任何可实现预期结果的代码的占位符:
struct CallInfo
{
const std::string m_function;
CallInfo(const std::string& function)
: m_function(function)
{
}
}
std::vector<CallInfo*> g_calledFunctions;
namespace mymath
{
// all functions with same return type, but differnent parameter lists
double sin(double radian)
{
g_calledFunctions.push_back(new CallInfo("sin"));
...
}
double atan2(double y, double x)
{
g_calledFunctions.push_back(new CallInfo("atan2"));
...
}
}
#define CALL_INFO_PREDICATE(functionName) [] (CallInfo* info) -> bool\
{\
static_assert_function_exists(mymath::functionName);/* << how to make this work? */\
return info->m_function == #functionName;\
}
int main ()
{
mymath::sin(1);
mymath::atan2(3, 7);
auto pos = std::find_if(g_calledFunctions.begin(), g_calledFunctions.end(), CALL_INFO_PREDICATE(sin)); // compiles; function sin exists in mymath
auto pos2 = std::find_if(g_calledFunctions.begin(), g_calledFunctions.end(), CALL_INFO_PREDICATE(cos)); // produces compile time error, since there is no function named cos in mymath
...
}
假设没有重载,您可以直接使用它:
#define CALL_INFO_PREDICATE(functionName) [] (CallInfo* info) -> bool \
{ \
static_cast<void>(&mymath::functionName); \
return info->m_function == #functionName; \
}
转换为 void
以避免对未使用的表达式发出警告。
为什么不将函数指针存储在 CallInfo
中并消除对宏的需要?
struct CallInfo
{
const std::string m_function;
void* m_function_ptr;
CallInfo(const std::string& function, void* function_ptr)
: m_function(function),
m_function_ptr(function_ptr)
{
}
}
std::vector<CallInfo*> g_calledFunctions;
namespace mymath
{
// all functions with same return type, but differnent parameter lists
double sin(double radian)
{
g_calledFunctions.push_back(new CallInfo("sin", sin));
...
}
double atan2(double y, double x)
{
g_calledFunctions.push_back(new CallInfo("atan2", atan2));
...
}
}
int main ()
{
mymath::sin(1);
mymath::atan2(3, 7);
auto pos = std::find_if(g_calledFunctions.begin(), g_calledFunctions.end(), [](CallInfo* info) { return info->m_function_ptr == &mymath::sin; });
auto pos2 = std::find_if(g_calledFunctions.begin(), g_calledFunctions.end(), [](CallInfo* info) { return info->m_function_ptr == &mymath::cos; });
// ...
}
现在编译器可以自动为您检查该函数是否存在。