【问题标题】:Create template class based on run time bool value根据运行时 bool 值创建模板类
【发布时间】:2015-08-29 00:54:29
【问题描述】:

如何在下面实现?我想为布尔值“预先创建”2个“Doer”模板类实例。我被虚拟机困住了吗?做这样的事情最有效的方法是什么?我知道 boost 变体,但不确定这是否最好用?基本上我希望能够为 bool 值提供 2 个“Doer”模板,因为 doer 的各个成员将根据 bool 值采取不同的操作。

struct Config
{
   int y;
};

template<typename DoerT>
class Aspect
{
   public:
         Aspect(bool b)
         {
            if(b) //can I create this way and pass around?
                _doer<true>(this);
            else 
                _doer<false>(this);
         }

         //will this work?
         DoerT doer() const { return _doer;}

   private:
     DoerT _doer;
};


template<typename ConfigT, bool b>
class Doer
{
  public:
    //how to create typedef for Aspect and objects that need "b"
        typedef Aspect<Doer<ConfigT,b> >* AspectT;

        //also can I then specialize member functions of OtherObject
        ///based on b?   There will be several other types here that
        //will need to perform tasks differently based on the bool.
        typedef OtherObject<ConfigT,b> OOT;

        Doer(AspectT asp) : _asp(asp) {}
        void doSomething(const Data& d) 
        {
        }

  private:
        AspectT _asp;
        OOT _obj;
};
//specialized members of Doer that need to behave differently based
//on bool..
template<Config,true>  template<> Doer::doSomething {..}
template<Config,false> template<> Doer::doSomething {..}



template<typename DoerT>
class Manager
{
   public:
         typedef Aspect<DoerT>* AspectPtr;

         void Load()
         {
            //retrieves data from database isNew returns bool
            Data dbData = GetDataFromDB();
            for(auto d : dbData)
            {
               //pass Boolean value to Aspect to create Doer templates
               rows[dbData.Name]= new AspectPtr<DoerT>(d.IsNew());
            }

         }
         AspectPtr Find(const std::string& name)
     {
    return rows[name];   
     }

  private:
        std::map<std::string,AspectPtr> rows;

};


class MXProcessor : Processor<Doer<Config, bool> > {...}


template<typename DoerT>
class Processor
{
   public:
      typedef Aspect<DoerT>* AspectPtr;
      typedef OtherObject1<DoerT>  obj1;
  typedef OtherObject2<DoerT>  obj2;
      void start()
      {
           _mgr.Load();
      } 
      void processData(const Data& d)
      {
            //lookup context row
            AspectPtr asp = _ctxMgr.Find(d.Name);
            asp->doer().doSomething(d);
      }

  private:
      Manager<DoerT>  _mgr;
      LogMgr<DoerT>  _lmgr;
};

int main() { //start MXProcessors}

【问题讨论】:

  • 这看起来相当循环。你能完全简化示例伪代码吗?
  • 我会尝试.. 我正在尝试为 bool 预先创建 Doer 模板,因此 Doer 的成员(函数和其他具有自己函数的类)不必经常检查if(true), else {}.. 我应该能够从 Doer 派生并使用 virtuals,但我想知道是否有更好的方法来处理仅 2 个可能的运行时值。
  • 很难看出你想要达到什么目标。为什么 bool 必须是模板参数? “doer 的各个成员将根据 bool 值采取不同的行动”并没有解释它。如果您担心在运行时重复检查 bool 的成本,您可能需要记住您将从分支预测中受益。如果您将 bool 设为模板参数,然后根据这两种类型制作 boost 变体……这有点循环。为什么不避免使用模板,制作可编译的东西,然后尝试优化。
  • 您的程序是否有多个Doer 实例?
  • 是的。我刚刚更新了代码。方面是根据数据库中返回的内容创建的。MX 处理器位于专用线程上。每个 MXProcessor 使用 Manager 来创建 Aspects。每个 Aspects 都有相同类型的 Doer。实干家有很多对象,现在需要根据布尔值表现出不同的行为。我必须在很多地方添加 if/else,并且有很多频繁的事件..

标签: c++ templates template-specialization partial-specialization


【解决方案1】:

模板是一种编译时构造。你不能指望 C++ 开箱即用。

这实际上是可能的,使用代码生成、内省(在 C++ 中也不容易获得)、编译和动态链接。但是你必须自己做。它不在语言中。它也不会像模板那么简单。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-05-16
    • 2011-01-19
    • 1970-01-01
    • 1970-01-01
    • 2013-12-11
    • 1970-01-01
    • 2022-01-17
    • 1970-01-01
    相关资源
    最近更新 更多