【问题标题】:static const array of values in Variadic Template C++可变参数模板 C++ 中的静态 const 值数组
【发布时间】:2014-05-15 17:51:28
【问题描述】:

我有一个函数,我希望能够在运行时检查参数类型,因为我将 void 指针转换回函数。好奇我如何使用 TypeToEnum 模板将参数列表转换为哈希

    #define DEFINE_TYPE(x)\
    template<>\
    struct TypeToEnum<x>\
    {\
      public:\
      static const unsigned int value = HashString(#x);\
    };\

这样我可以使用模板确定函数签名。我只是没有 了解如何在调用方法中将其转换为静态 const 数组。

    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...);
}
};

【问题讨论】:

  • 什么是数据类型?你有什么理由不能只使用std::function
  • 我原本打算不使用哈希方法,但经过一番折腾之后,我得到了一个哈希类型的方法,可以在没有 constexpr 的 Visual Studio 中工作。只是没有更新我的代码。更正了。我想要一个不同调用签名的函数列表。我计划最终添加一个方法,该方法将采用序列化数据流并使用运行时信息来调用函数(可能必须进行一些组装并且不可移植),但我也希望这种调用样式方法也能工作。也不知道怎么做,但想先弄清楚这个。

标签: c++ templates c++11 constants variadic-templates


【解决方案1】:

TypeToEnum&lt;std::forward&lt;Args&gt;&gt;::valueTypeToEnum&lt;Args&gt;::value...,但我会这样做

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) ) 说“我希望这个参数是一个引用”。

接下来,我会考虑使用typeid,而不是你所有的机器。除其他问题外,您的哈希值并不完全可靠。

【讨论】:

  • 谢谢。 std::decay 我不知道。它有很大帮助。关于 typeid 我的一件事是我希望我的哈希码在编译器中保持不变。所以“int”的hash_code无论如何都是一样的。环顾四周,我没有看到可以保证这一点的规范。
猜你喜欢
  • 1970-01-01
  • 2011-08-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多