Variadic模板C ++中的值的静态const数组 [英] static const array of values in Variadic Template C++
问题描述
我有一个函数,希望在我将void指针投射回函数时可以在运行时检查其参数类型。好奇如何使用TypeToEnum模板将参数列表转换为哈希,该模板的构建方式如下:
I have a function that I want to be able to runtime check the argument types of as I'm casting a void pointer back to a function. Curious as to how I turn the list of arguments into into a hash using the TypeToEnum template that is constructed like
#define DEFINE_TYPE(x)\
template<>\
struct TypeToEnum<x>\
{\
public:\
static const unsigned int value = HashString(#x);\
};\
这样我可以确定使用模板的功能签名。我只是不知道如何在invoke方法中将其转换为静态const数组。
That way I can determine the function signature using templates. I just have no idea how to convert that into a static const array in the invoke method.
class FunctionDescription
{
private:
int return_type;
std::vector<int> argument_types;
std::string m_name;
void* function;
public:
const std::string& name() const{ return m_name; }
int ReturnType() const { return return_type; }
const std::vector<int>& arguments() const { return argument_types; }
template<typename Return,typename... Args>
FunctionDescription(const std::string& _name, Return(*func)(Args...))
: m_name(_name), return_type(TypeToEnum<Return>::value)
{
argument_types = { TypeToEnum<Args>::value... };
function = func;
}
template<typename Return,typename... Args>
Return invoke(Args... args)
{
static const int type_check[] = {TypeToEnum<Return>::value,TypeToEnum<std::forward<Args>>::value};
if (type_check[0] != return_type)
throw std::exception("Invalid return type for given call");
for (int i = 1; i < sizeof...(Args) + 1; i++)
{
if (type_check[i] != argument_types[i])
throw std::exception("Invalid argument type for the given call");
}
return Return(*func)(Args...)(args...);
}
};
推荐答案
TypeToEnum< std ::将< Args>> :: value
转发到 TypeToEnum< Args> :: value ...
,但我还是选择
TypeToEnum<std::forward<Args>>::value
to TypeToEnum<Args>::value...
, but I'd instead do
template<typename Return,typename... Args>
Return invoke(Args...&& args){
static const int type_check[] = {
TypeToEnum<Return>::value,TypeToEnum<typename std::decay<Args>::type>::value...
};
if (type_check[0] != return_type)
throw std::exception("Invalid return type for given call");
for (int i = 1; i <= sizeof...(Args); i++)
{
if (type_check[i] != argument_types[i])
throw std::exception("Invalid argument type for the given call");
}
typedef Return(*func_t)(typename std::decay<Args>::type...);
return static_cast<func_t>(function)( std::forward<Args>(args) );
}
作为第一遍。然后,我将使用自定义类型映射替换 decay
,该自定义类型映射可以正确处理 std :: reference_wrapper
,因此调用者可以说通过说 invoke(std :: ref(x))
来期望此参数是ref。
as a first pass. I would then replace decay
with a custom type mapping that handles std::reference_wrapper
properly, so callers can say "I expect this argument to be a ref" by saying invoke( std::ref(x) )
.
下一步,我会考虑使用 typeid
代替您的所有设备。除了其他问题外,您的哈希还不够可靠。
Next, I would consider using the typeid
instead of all of your machinery. Your hash isn't perfectly reliable, among other problems.
这篇关于Variadic模板C ++中的值的静态const数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!