使用模板自定义RTTI信息

时间:2016-01-24 07:16:39

标签: c++ templates rtti

我有SpiderMonkey API的包装类,我需要定义具有特定签名的方法。我有一个基于模板的解决方案。基本上,我有几个模板方法来处理数百个包装器方法,如(简化):

template <typename jsType, AIErr(*Type::*Method)()>
    static bool ExecuteMethod(JSContext *cx, unsigned argc, JS::Value *vp)
{
...
}

我使用宏如下使用它:

#define EXECUTE_METHOD_AIERR_X(TYPE, METHOD) \
JS_FN(#METHOD, (js##TYPE::ExecuteMethod<js##TYPE, &TYPE::METHOD>), 0, 0)

如果我有需要调试的情况,为了知道在特定时间处理了哪个类(* Type)的哪个方法(* Method),我需要知道该名称在该模板方法中输入 Type 和方法名称​​ Method 。由于SpiderMonkey的API的性质,我无法改变ExecuteMethod的参数,只能改变模板。

我见过这些:

C++ Get name of type in template

C++ Template Specialization with Constant Value

我已经尝试过这些,但是在MSVC C ++ 2013编译器的typeid(T).name()步骤中解决方案失败了。另一方面,如何在方法上应用它?

另外,我看到了:

template<typename T>
class TypeParseTraits{
public:
    static const std::string name(){
        return typeid(T).name();
    }
};

#define REGISTER_PARSE_TYPE(X) \
    template<> class TypeParseTraits< X > \
    { public: static const std::string name(){ return #X; } };

这是template<> class TypeParseTraits< X >是什么?覆盖?专业化?

如果我再次使用模板,则必须依赖于jsType,Type和Method。

我的问题是,我应该如何使用字符串实现(甚至仅用于调试)RTTI信息?什么是最有效的选择,如果有的话?

我知道简单的char *不是模板参数的选项。

谢谢。

1 个答案:

答案 0 :(得分:2)

&#34; 这是什么模板&lt;&gt; class TypeParseTraits&lt; X&gt;?覆盖?专业化?&#34; - 它是模板的部分特化。在这种特殊情况下,给定的宏确保 TypeParseTraits 模板实例化为&#39;注册&#39; type将具有方法 name ,它返回const std :: string,其中包含类型的名称,在代码中使用而不是任何返回的type_info.name()(这是实现 - 定义且通常难以理解。)

我的问题是,我应该如何使用字符串实现(甚至仅用于调试)RTTI信息?什么是最有效的选项,如果有的话? - RTTI的最佳方法应该是一些虚拟方法,它将返回例如一个字符串。应该在所有派生类中重写此方法(可以使用静态多态方法简化)并返回相应的信息。

我知道简单的char 不是模板参数的选项。* - 不是一般的,但是......

  • 可以在struct或class
  • 中使用静态const char *数据
  • 可以在模板
  • 的帮助下填充此数据
  • 可以传递这样的结构作为模板参数并提取静态数据
  • 如果会员 constexpr (虽然有一些处罚),可以手动填写这些字符串

因此,您可以使用类型(可能是模板)将char *传递到其他模板中。

示例:

public void configure(HttpSecurity http) throws Exception {
    http.antMatcher("/**")
            .authorizeRequests()
            .antMatchers("/", "/login**").hasRole("user")
            .anyRequest().authenticated()
    .and()
            .exceptionHandling()
                .authenticationEntryPoint(authenticationEntryPoint());
}

private AuthenticationEntryPoint authenticationEntryPoint() {
    return new AuthenticationEntryPoint() {
        // You can use a lambda here
        @Override
        public void commence(HttpServletRequest aRequest, HttpServletResponse aResponse,
               AuthenticationException aAuthException) throws IOException, ServletException {
            aResponse.sendRedirect(MY_AS_URL + "?redirect_uri=localhost:9001/home");
        }
    };
}