【问题标题】:C++ Transporting runtime-conditional type informationC++ 传输运行时条件类型信息
【发布时间】:2016-08-30 08:33:29
【问题描述】:

我有一个有 4 种索引类型的数据库。每个索引类型都有一个排序顺序。也就是说,如果您知道静态索引类型,那么就有一个正确的函子可用于对该索引中的对象进行排序,并且只要您知道索引类型,即在编译时静态地,它也被称为。

数据库有一个函数,它包含一个运行时 switch 语句来决定与哪个索引对话。我希望该函数从索引(主要是迭代器)返回运行时信息,还希望使用静态订单类型。

为了表明意图,这里有一些伪代码。它不能按原样工作......是否可以使用模板特化来编写 getLookupInfo (返回类型将是多态的)。注意:我不想使用虚拟。

template <typename Iterator, typename Order>
struct LookupInfo {
  typedef Order order;
  uint64_t cost;
  Iterator it1, it2, it3, it4;
};

LookupInfo Database::getLookupInfo(LookupData data)
{
  if (data == ....) {
   return LookupInfo<Iterator1, Order1>();
  } 
   return LookupInfo<Iterator2, Order2>();
}

some_function(LookupInfo lookup_info) {
  vector<Record> records(lookup_info.begin(), lookup_info.end());
  sort(records.begin(), records.end(), lookup_info::order());
}

这样的事情可能吗?

【问题讨论】:

  • 我很好奇您期望getLookupInfo 的工作方式。我不明白它怎么可能被调用。返回语句与返回类型不匹配,这意味着您需要多态或模板特化。
  • 安迪 - 是的 - 这就是我无法关闭循环的地方。代码 sn-p 将不起作用,它更旨在显示我想做的事情。你是对的,诀窍是让 getLookupInfo 的返回类型每次都返回不同的类型。我不想要虚拟,所以我想使用模板专业化。但即使是恕我直言也很棘手。我的问题的本质大概是:如何使用模板特化来写getLookupInfo?
  • 诀窍是把所有东西都变成一个类型......如果你给我一些你想如何调用它的伪代码(没有模板专业化),我可能会提供帮助。
  • OK - getLookupInfo 中的内容也可能是一个 int,它的值决定了使用哪种类型的 Order。 getLookupInfo 出来的应该是类似于上面的 LookupInfo 的东西,它携带一些东西,加上类型 Order。如果 virtuals 是可能的,我猜 LookupInfo 上会有一个 virtual 来检索 Order 的实例。这有意义吗?
  • 如果您将所有可能的LookupInfo 类型存储在一个元组中,而getLookupInfo 将结果存储在该元组中,并返回一个索引呢?您还需要模板some_function。还要检查boost fusion,这可能对您的问题很有趣

标签: c++ templates c++11 metaprogramming template-meta-programming


【解决方案1】:

您可以通过折叠 getLookupInfo -> 将 some_function 序列应用到单个调度序列中来实现。首先,让我们更正您对 some_function 的定义,以反映它是一个模板函数这一事实:

template<typename LookupInfo>
void some_function(LookupInfo lookup)
{
    vector<Record> records(lookup_info.begin(), lookup_info.end());
    sort(records.begin(), records.end(), lookup_info::order());
}

接下来,引入一个辅助函子来调用它(由于我在下面讨论的原因,我不能跳过这个,就像我想的那样):

template<typename LookupInfo>
struct some_functor
{
    void operator()(LookupInfo lookup_info)
    {   
        some_function<LookupInfo>(lookup_info);
    }   
};

现在是调度技巧。忘记上面的 getLookupInfo 函数,而是定义:

template<template <class L> class F>
void dispatchLookupInfo(int data)
{
  if (data == 0) {
    auto lookup = LookupInfo<Iterator1, Order1>();
    F<LookupInfo<Iterator1, Order1>> fn; 
    fn(lookup);
  }
  else  {
    auto lookup = LookupInfo<Iterator2, Order2>();
    F<LookupInfo<Iterator2, Order2>> fn; 
    fn(lookup);
  }   
} 

注意这里我假装data 是一个int,正如你所说的那样。如您所见,我们不是先获取 LookupInfo 然后单独调用该函数,而是一次性完成。这里 dispatchLookupInfo 接受一个模板模板参数,所以它可以专门化任何函数。这又回到了我需要一个辅助函子的观点:我还没有找到一种方法来将函数模板(而不是类模板)作为模板模板参数传递。但是,虽然笨重,但我相信它可以满足您不涉及虚拟通话的要求。您的最终调用可能如下所示:

dispatchLookupInfo<some_functor>(0);

【讨论】:

    猜你喜欢
    • 2010-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-21
    • 2011-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多