簡體   English   中英

C ++模板按枚舉指定類型

[英]C++ template specify type by Enum

我面臨一個問題:我想創建一個函數,該函數根據函數將接收的枚舉來調用特定的模板類型構造函數。 我的意思是:

  typedef   ____ (Class<whatever>::*tabType)(int flag);

  template<typename T>
  static Class*  Class<t>::createClassInstance(enum precision)
  {
    static const ___ createTab[] = {
    Class<int>,
    Class<double>
    }
   return (new createTab[precision](1));
  }

有很多方法可以實現這種目的,但是聽起來您想創建一個由enum變量索引的工廠方法的數組(或映射)(每個類一個)。 每個調用相關的構造函數,並返回該類型的新對象。

當然,要使之有意義,所有類都必須派生自一個共同的基礎。

如果枚舉值作為函數參數是動態的,則必須使用調度表或switch / if-else。 請注意,您的偽代碼並未明確說明要求。 假設您要定義的createInstance函數到底是什么,將如何調用它?

我會說,只需構造一個將enum映射到工廠函數的std::mapboost::function<> )。 然后,您只需為每種類型添加一個條目,並帶有相應的enum 實際構造工廠功能。 您可以為每個類都具有一些static Create()函數並存儲一個函數指針。 或者,您可以使用Boost.Lambda 構造函數/析構函數函子。 或者,您可以使用Boost.Bind構造函子,該函子包裝需要一些參數的工廠函數。 這是一個例子:

#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <boost/lambda/construct.hpp>
#include <map>

struct Base { };

struct Derived1 : public Base { };

struct Derived2 : public Base {
  static Base* Create() { return new Derived2; };
};

struct Derived3 : public Base {
  int value;
  Derived3(int aValue) : value(aValue) { };
  static Base* Create(int aValue) { return new Derived3(aValue); };
};

enum DerivedCreate { ClassDerived1, ClassDerived2, ClassDerived3 };

int main() {
  std::map< DerivedCreate, boost::function< Base*() > constructor_map;
  constructor_map[ClassDerived1] = boost::lambda::new_ptr<Derived1>();
  constructor_map[ClassDerived2] = &Derived2::Create;
  constructor_map[ClassDerived3] = boost::bind(&Derived3::Create, 42);

  //now you can call any constructor as so:
  Base* ptr = constructor_map[ClassDerived2]();
};

我可能在語法上犯了一些小錯誤,但是基本上您應該可以完成上述工作。 同樣,您擁有多個類模板的事實也沒有作用,一旦將它們實例化為具體的類(例如Class<int>Class<double> ),它們便與其他任何類一樣,並且上述想法應保持有效。

擴展您的示例,類似以下內容的工作:

enum Prec {INT, DOUBLE};

struct Base
{
    virtual ~Base () = 0 {}
};

template<typename T> struct Class : public Base
{
    static Base* create (int flag) {return new Class<T> (flag);}
    Class (int flag) {}
};

typedef Base* (*Creator) (int flag);

Base* createClassInstance (Prec prec)
{
    static const Creator createTab[] = {
        Class<int>::create,
        Class<double>::create
    };

    return createTab[prec] (1);
}

int main (int argc, char* argv[])
{
    Base* c = createClassInstance (DOUBLE);

    return 0;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM