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

时间:2013-07-18 02:01:30

标签: c++ templates

我试着睡在这上面,但仍然输了。我甚至不确定我应该使用哪些搜索词。有人能指出我正确的方向。

我想要这样的事情:

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_two选择phase_one。所有这些都是在读取文件的BOM后在运行时完成的。

我更喜欢在没有boost或c ++ 11的情况下这样做。 如果有一个这样的boost方法,我会很高兴看到它,但它必须是没有boost库的可实现,即使我必须自己创建一个类似的方法/模板。

3 个答案:

答案 0 :(得分:0)

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

}

这对你有用吗?

答案 1 :(得分:0)

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

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

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

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

答案 2 :(得分:0)

我知道你想要提升,但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 ) );
}

也许这不是你想要的,但需要考虑的事情。