簡體   English   中英

將未知類型的模板化類傳遞給untemplated類構造函數

[英]Passing templated class with unknown type to untemplated class constructor

我有兩個類,我們稱之為SomeClass和OtherClass。

SomeClass是模板化的:

template <typename T> class SomeClass
{
public:
    SomeClass (const T& value);
};

OtherClass不是模板化的,而是使用SomeClass。

class OtherClass
{
public:
    OtherClass (const SomeClass& c, const std::string s);
};

應該以這種方式調用它們:

SomeClass<int> some(5);
OtherClass other(some, "hello, world!");

other.doSomethingWithSome();

...顯然,這將無法編譯,因為編譯器需要知道SomeClass的類型...

對我來說不幸的是,SomeClass的類型幾乎可以是任何東西(盡管使用的實際類型的數量是有限的,只是無關的),並且在開發過程中可能經常發生變化。 (我知道,我知道,我想我真的可以使用SomeClass'類型並將其傳遞給模板化的OtherClass,但由於存在許多實例,因此它非常繁瑣;而且,我想假裝兩個班都不知道其他人的工作。:))

問題很簡單:我該如何使用這種語法? (無需模板化OtherClass。)

一個明顯的答案是你可以使SomeClass繼承自非模板抽象類:

template <typename T>
class SomeClass : public SomeAbstractBase
{
    /* ... */
};

而反過來, OtherClass將在SomeAbstractBase工作:

class OtherClass
{
public:
    OtherClass (const SomeAbstractBase& c, const std::string s);
};

你並沒有真正給予足夠的肯定,在適當的解決方案中,但它可能是。 最后,如果您在編寫SomeAbstractBase沒有問題(即:您很容易設法識別所有SomeClass<T>的共同點),那么可能就是這樣。

您使用類型隱藏:

class OtherClass
{
public:
  template < typename T >
  OtherClass(SomeClass<T> const& c, std::string const& s)
    : pimpl(new impl<T>(c))
    , str(s)
  {}

  void doSomething() { pimpl->doSomething(str); }

private:
  struct impl_base { virtual ~impl_base() {} virtual void doSomething(std::string) { ... }};
  template < typename T >
  struct impl : impl_base
  {
    impl(T const& )...
  };

  scoped_ptr<impl_base> pimpl;
};

您將需要模板化OtherClass - 或者 - 專門化OtherClass構造函數以接受您需要傳遞的SomeClass類型。

// Otherclass can take objects of any type now
template <typename T> class OtherClass
{
public:
    OtherClass(SomeClass<T>& someclass..);
};

// or

class OtherClass
{
    // specialize the otherclass constructor
    OtherClass(SomeClass<int> someclass ..)
}

目前尚不清楚你正在嘗試做什么。 但是模板化的構造函數呢?

class OtherClass {
public:
  template <typename T> OtherClass(const SomeClass<T>& c, const std::string& s);
  // ...
};

當然,如果例如, OtherClass需要SomeClass<T>類型的成員,那么這將不起作用。

使用編譯時(模板)和運行時多態(虛擬):

class MyBase {
public: 
   virtual void foo() = 0;
}


template <class T>
class SomeClass : public MyBase {
public:

   void foo () {
     // do T-specific stuff
   }
}

然后, OtherClass接受一個MyBase*OtherClass::doSomethingWithSome調用它的虛擬foo方法。

暫無
暫無

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

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