【问题标题】:Handle templates with unknown until runtime type处理直到运行时类型未知的模板
【发布时间】:2013-07-19 00:16:20
【问题描述】:

我试着睡在上面,但还是迷路了。我什至不确定我应该使用什么搜索词。有人能指出我正确的方向吗?

我想要这样的东西:

template < typename Interim >
class phase_one
{
    Interim do_something () ;
}
template < typename Output, typename Interim >
class phase_two
{
    Output do_something_more ( Interim ) ;
}
template < Output >
class main_class
{
    phase_one m_first;
    phase_two m_second;

    Output do_main ( )
    {
        return m_second.dosomething_more( m_first.do_something() );
    }
}

希望您能从伪代码中看到我需要在两个模板类上存储和调用。但是Interim 类型直到运行时才知道。我事先知道的唯一一件事是 Output 类型以及两个阶段具有共同类型的事实。

如何存储这些对象以及如何使它们协同工作? 这是需要类型擦除的实例吗?

编辑: phase_one 将是 std::codecvtphase_two 将是我创作的另一个 codecvt。我需要根据phase_one 选择phase_two。所有这些都是在运行时完成的,在读取文件的 BOM 之后。

我宁愿在没有 boost 或 c++11 的情况下这样做。 如果有这样做的 boost 方法,我会很感兴趣,但它必须可以在没有 boost 库的情况下实现,即使我必须自己创建一个类似的方法/模板。

【问题讨论】:

  • @jogojapan 读取文件的 BOM,Interim 设置为适合读取该文件的类型,因此它可以是 char unsigned shortunsigned long。输出类型将是用户需要的字符串处理类型,可能是charwchar_t
  • @Waldermort 你有没有想过在虚函数中使用多态性?通过创建 main_class 的新实例,为 main_class 和交换实现创建一个“接口”。
  • 如果可能性的数量是有限的并且数量很小,您可以强制实例化所有案例,然后在运行时选择正确的案例。
  • @Lalaland 我仍然需要对所有排列进行硬编码,然后虚函数会导致性能损失。
  • 更新帖子以反映这些细节。

标签: c++ templates


【解决方案1】:

我修改了你的 main_class 模板。基本上让它知道Interim类型

template < typename Interim >
class phase_one
{
    Interim do_something () ;
}

template < typename Output, typename Interim >
class phase_two
{
    Output do_something_more ( Interim ) ;
}

template < typename Output, typename Interim >
class main_class
{
    phase_one<Interim> m_first;
    phase_two<Output, Interim> m_second;

    Output do_main ( )
    {
        return m_second.dosomething_more( m_first.do_something() );
    }
}

你像这样实例化 main_class

int main () {

    if (some condition) {
         main_class<char, unsigned long> m;
         m.do_main();
    } else {
         main_class<char, unsigned short> m;
         m.do_main();
    }

}

这对你有用吗?

【讨论】:

  • m 在该范围内不存在。
  • 愚蠢的错误.. 编辑了答案。反正修改后的 main_class 模板做你想做的事吗?
  • 某些条件只有在运行时才知道,使得代码需要编译到每个可以想象的中间
  • 要使其工作,您需要生成临时可能具有的所有可能排列。例如,一个用于实型、double、int、unsigned int 等......
  • 由于问题的性质,我只能想象一个基于多态性的解决方案
【解决方案2】:

我想提出非 C++ 解决方案。

对于这种情况,我想说你需要知道可能的 Interim 类型。

即使对于像 C# 和 Java 这样可以在运行时获取类型的语言,您仍然需要清楚知道可能的类型集,否则如何确保您的代码对该类型有意义?

所以基于@ubi answere,编写一个开关来处理它,如果编写一个大型开关案例来处理每种类型的成本很高,建议你编写一个脚本工具来从可能的临时类型生成代码编译项目时列出。

【讨论】:

    【解决方案3】:

    我知道你不想要提升,但boost::variant 或许可以帮助你。它允许您定义“联合”类型,其中您的变量可以存储多种可能类型中的一种。然后,您可以应用一个函数(称为“访问者”),该函数由运行时确定,具体取决于变量中实际存储的数据类型。我发现它很快就会变得非常笨拙,但它可能会对你有所帮助。

    我正在想象您将您的m_first 定义为boost::variant,然后使用将您的phase_one::do_something 声明为“访问者”类的operator(),因此您的行会变成这样:

    Output do_main ( )
    {
        return m_second.dosomething_more(
           boost::apply_visitor( phase_one(), m_first ) );
    }
    

    也许这不是您要寻找的东西,而是需要考虑的东西。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-09-19
      • 1970-01-01
      • 1970-01-01
      • 2011-08-18
      • 1970-01-01
      • 2011-08-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多