[英]How can you pass a function pointer and compare it in a function in C++?
For testing reasons I have a certain number of methods whose signature in C++ would look like: 出于测试原因,我有一定数量的方法,其在C ++中的签名如下所示:
dvec3 (*)(dvec3, dvec3, double)
I put them in a vector as follows: 我将它们放在向量中,如下所示:
vector<dvec3 (*)(dvec3, dvec3, double)> methods = {lerp, plerp, splerp, ilerp};
The idea is to make a function that takes the function pointer and returns a string to identify the function that is currently being used (ie I want to print out which function, among the 4 above, is being used) 想法是制作一个带有函数指针并返回字符串的函数,以标识当前正在使用的函数(即,我要打印出上面四个函数中的哪个函数)
For this I attempted to write the method as follows (I ommitted most cases on purpose): 为此,我尝试编写如下方法(故意省略了大多数情况):
string inline erpToString(dvec3 (*f)(dvec3, dvec3, double))
{
if (f==lerp)
{
return "Lerp";
}
}
The above however does not compile, the error message states that it's a casting error. 但是以上代码无法编译,错误消息指出这是强制转换错误。 What did I do wrong?
我做错了什么?
EDIT: 编辑:
Compiler message: 编译器消息:
/home/kronos/Desktop/OpenGL-Template/source/Rendering/rendering.cpp: In function ‘std::__cxx11::string erpToString(glm::dvec3* (*)(glm::dvec3, glm::dvec3, double))’:
/home/kronos/Desktop/OpenGL-Template/source/Rendering/rendering.cpp:1362:7: error: invalid operands of types ‘glm::dvec3* (*)(glm::dvec3, glm::dvec3, double) {aka glm::tvec3<double, (glm::precision)0>* (*)(glm::tvec3<double, (glm::precision)0>, glm::tvec3<double, (glm::precision)0>, double)}’ and ‘<unresolved overloaded function type>’ to binary ‘operator==’
if (f==lerp)
~^~~~~~
make[2]: *** [CMakeFiles/voxel-world.dir/build.make:111: CMakeFiles/voxel-world.dir/source/Rendering/rendering.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:68: CMakeFiles/voxel-world.dir/all] Error 2
EDIT: 编辑:
I have made the minimum possible file that would have the same logic, however it does not reproduce the error: 我已经制作了具有相同逻辑的最小文件,但是它不会重现该错误:
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <string>
using namespace std;
using namespace glm;
dvec3 lerp(dvec3 p1, dvec3 p2, double t)
{
return (1-t)*p1+t*p2;
}
string inline erpToString(dvec3 (*f)(dvec3, dvec3, double))
{
if (f==lerp)
{
return "Lerp";
}
}
int main()
{
}
Playing around with the code shows the other methods (ilerp and company) do work. 遍历代码可以显示其他方法(ilerp和company)可以正常工作。 So it seems I have a namespace conflict (yay for using namespaces).
所以看来我有一个命名空间冲突(是使用命名空间的原因)。 SInce GLM defines a lerp function, but the one I need to use is the one I defined.
因为GLM定义了一个lerp函数,但是我需要使用的是我定义的一个。 Anyone got a suggestion?
有人有建议吗?
You could use using
or typedef
to simplify all thing. 您可以使用
using
或typedef
简化所有操作。 Code works for me 代码对我有用
int a(float x, float y, double z)
{
return int(x + y + z);
}
int b(float x, float y, double z)
{
return int(x - y - z);
}
using fdef = int(*)(float, float, double); // or typedef int (*fdef)(float, float, double);
std::vector<fdef> v{a, b};
if (v[0] == a)
std::cout << "qqq\n";
The problem was caused because GLM defines a lerp Function as well, thus the compiler couldn't choose which function I was referring too. 造成此问题的原因是,GLM还定义了一个lerp函数,因此编译器也无法选择我要引用的函数。
The solution was, as suggested in the comments, renaming my function from lerp
to mlerp
如评论中所建议,解决方案将我的功能从
lerp
重命名为mlerp
I guess this is a very good example as to why using namespaces is not a great idea. 我猜这是一个很好的例子,说明为什么使用命名空间不是一个好主意。
This is not an answer to how to fix the bug, but an answer to your attemp of giving a name of the method your are using. 这不是解决错误的答案,而是对您尝试使用的方法名称的尝试的答案。
I suggest you to use std::unordered_map to discriminate different functions. 我建议您使用std :: unordered_map来区分不同的功能。
std::unordered_map<void*, const char*> funcmap{4};
union cast_fptr {
dvec3 (*)(dvec3, dvec3, double) fptr;
void *void_ptr;
};
#define MAP_VAL(FUNC_NAME) std::pair<void*, const char*>{cast_fptr{.fptr = &FUNC_NAME}.void_ptr, #FUNC_NAME}
funcmap.insert({MAP_VAL(lerp), MAP_VAL(plerp), MAP_VAL(splerp), MAP_VAL(ilerp)});
#undef MAP_VAL
inline const char* erpToString(dvec3 (*f)(dvec3, dvec3, double)) noexcept {
return funcmap[f];
}
The key is '<unresolved overloaded function type>'
关键是
'<unresolved overloaded function type>'
In particular, you have two lerp
functions. 特别是,您有两个
lerp
函数。 That's generally allowed. 通常是允许的。 In most contexts, C++ will figure out which one you want.
在大多数情况下,C ++会找出您想要的那个。 For instance, when you call
lerp(arg1,arg2, arg3)
, C++ will do overload resolution with those three arguments. 例如,当您调用
lerp(arg1,arg2, arg3)
,C ++将使用这三个参数进行重载解析。 But in f==lerp
, there are no three arguments for overload resolution. 但是在
f==lerp
,没有用于重载解析的三个参数。 That is why C++ says "unresolved overload". 这就是C ++说“未解决的重载”的原因。
The solution is to cast lerp
to the type of f: if (f==static_cast<decltype(f)>(&lerp))
. 解决方案是将
lerp
转换为f的类型: if (f==static_cast<decltype(f)>(&lerp))
。 The three arguments to use for overload resolution are those of f
. 用于重载解析的三个参数是
f
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.