处理运行时类型未知的模板

Handle templates with unknown until runtime type

本文关键字:未知 运行时 类型 处理      更新时间:2023-10-16

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

我想要这样的东西:

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 库的情况下实现,即使我必须自己创建一个类似的方法/模板。

我修改了你的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();
    }
}

这对你有用吗?

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

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

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

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

我知道

不想要提升,但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 ) );
}

也许这不是你要找的,而是需要考虑的事情。