以最少的样板消除dynamic_cast代码生成的开销

问题描述 投票:0回答:1

如何获取所有必要的信息,以便在运行时从下面的代码中打印“dynamic_cast(p)->eval()”的等效更快的代码字符串? (请在代码示例下面找到代码生成器背景/上下文)

#include<iostream>
#include<string>
#include"lib_typename.hpp" // template<typename T> typename_of<T>() returns string "T"; cf., e.g., in Boost

struct X;

struct A{
    virtual std::string my_typename()const{ return typename_of<A>(); }
    virtual ~A(){};
};

struct B{
    virtual std::string my_typename()const{ return typename_of<B>(); }
    virtual void eval()=0;
};

template<typename T>
struct C: A,B{
    virtual std::string my_typename()const{ return typename_of<C<T>>(); }
    void eval(){} 
};

int main(){
    C<X> c;
    A& p = c;
    
    dynamic_cast< B& >(p).eval();   // <-- I can generate that, but it is slow.
    static_cast< C<X>& >(p).eval(); // <-- This is fast, but where do I get the string "C<X>" from?
    
    // possible ways to find the string:
    std::cout << p.my_typename() << "\n";     // necessitates tons of boilerplate.
    std::cout << typeid(C<X>).name() << "\n"; // returns gibberish.
}

解释:“dynamic_cast(p).eval()”行是由我构建的代码生成器生成的。在生成时,我手头上的信息是

A& p
指的是
B
的非抽象派生。

我目前最喜欢的是样板选项,这样我的代码生成器最终可以生成更快的代码“static_cast(p).eval()”。但是有没有可能用更少的样板来实现呢?

背景:我的应用程序是一个基于模板的代码生成器。有些人可能会将此本身称为 xy 问题,但我的 x 工作(除了上面的,我可以忍受)令人满意。这个问题很模糊,因为我同样对不识别字符串“

C<X>
”的替代解决方案感到满意。

最后评论:我添加了模板参数

X
作为最小反例,以表明找到
A
B
的第一个共同继承者不足以解决问题。

c++ templates multiple-inheritance dynamic-cast static-cast
1个回答
0
投票

基于 @CraigEstey 的非凡“盲目猜测”,以下解决方案遵循样板方法,同时通过 CRTP 继承替换它来减轻一些样板:


// add struct
struct Crtp<typename T=void>{
    virtual std::string my_typename()const{ return typename_of<T>(); }
};

struct B:Crtp<B>{
    virtual void eval()=0;
};

template<typename T>
struct C: A,B,Crtp<C<T>>{
    void eval(){} 
};

字符串

Crtp<structname>
本质上应该使样板
virtual std::string my_typename()const{ return typename_of<structname>(); }
变得不必要,但我还没有测试过它。我还不确定。欢迎大家提出解决方案。

© www.soinside.com 2019 - 2024. All rights reserved.