将未知类型的模板化类传递给untemplated类构造函数

时间:2010-12-21 18:55:00

标签: c++ templates

我有两个类,我们称之为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。)

5 个答案:

答案 0 :(得分:6)

一个明显的答案是你可以使SomeClass继承自非模板抽象类:

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

反过来,OtherClass将适用于SomeAbstractBase

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

你并没有给予足够的肯定,在适当的解决方案中,但它可能是。最后,如果您在编写SomeAbstractBase时没有问题(即:您很容易识别出所有SomeClass<T>的共同点),那么可能就好了。

答案 1 :(得分:3)

您使用类型隐藏:

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;
};

答案 2 :(得分:1)

您需要模板化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 ..)
}

答案 3 :(得分:0)

目前尚不清楚你究竟要做什么。但是模板化的构造函数呢?

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

当然,如果OtherClass需要SomeClass<T>类型的成员,这将无效。

答案 4 :(得分:0)

使用编译时(模板)和运行时多态(虚拟):

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方法。