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

3

我试着休息一下,但还是无法解决问题。我甚至不确定应该使用什么搜索词。有人可以指点我正确的方向吗?

我想要类似于这样的东西:

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::codecvt,而phase_two将是我创建的另一个codecvt。我需要根据phase_one选择phase_two。而所有这些都是在运行时完成的,在读取文件的BOM之后。
我更喜欢不使用boost或c++11来完成这个任务。 如果有一种使用boost方法可以做到这一点,我会很感兴趣,但必须能够在没有boost库的情况下实现,即使我必须自己创建类似的方法/模板。

@jogojapan 读取文件的BOM,并将“Interim”设置为适合读取该文件的类型,因此它可以是“char”、“unsigned short”或“unsigned long”。输出类型将是用户所需的字符串处理类型,可能是“char”或“wchar_t”。 - Twifty
@Waldermort,你有没有考虑使用带有虚函数的多态性?为main_class创建一个“接口”,通过创建main_class的新实例来交换实现。 - user406009
如果可能性的数量是有限的,并且该数字很小,您可以强制实例化所有情况,然后在运行时选择正确的情况。 - Borgleader
@Waldermort 认为虚函数会导致性能损失是过早的优化,很可能不会改变任何事情。先进行分析,后进行优化。 - Borgleader
2
更新帖子以反映这些细节。 - Twifty
显示剩余6条评论
3个回答

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
m在该范围内不存在。 - user406009
愚蠢的错误..已经编辑了答案。不管怎样,修改后的main_class模板是否符合您的要求? - ubi
某些条件只有在运行时才能确定,这使得代码需要编译到每个可能的中间状态。 - Amadeus
为了使这个工作正常运行,您需要生成interim可能具有的所有可能排列。例如,一个用于实际类型,双精度,整数,无符号整数等... - Amadeus
1
由于问题的本质,我只能想象一个基于多态性的解决方案。 - Amadeus
显示剩余5条评论

0

我知道你不想使用boost,但是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 ) );
}

也许这不是你寻找的内容,但可以考虑一下。

0

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

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

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

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接