简体   繁体   English

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

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

I have two classes, lets call them SomeClass and OtherClass. 我有两个类,我们称之为SomeClass和OtherClass。

SomeClass is templated: SomeClass是模板化的:

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

OtherClass isn't templated, but uses SomeClass. OtherClass不是模板化的,而是使用SomeClass。

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

They are supposed to be called this way: 应该以这种方式调用它们:

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

other.doSomethingWithSome();

...Obviously, this will fail to compile since the compiler needs to know SomeClass' type... ...显然,这将无法编译,因为编译器需要知道SomeClass的类型...

Unfortunately for me, the type of SomeClass can be pretty much anything (though the number of actual types used are limited, just unrelated), and might frequently change while in development. 对我来说不幸的是,SomeClass的类型几乎可以是任何东西(尽管使用的实际类型的数量是有限的,只是无关的),并且在开发过程中可能经常发生变化。 (I know, I know, I suppose I really could use SomeClass' type and pass it to a templated OtherClass, but its quite a tedious job since there are some many instances; also, I'd like to pretend neither class knows about the other's workings. :) ) (我知道,我知道,我想我真的可以使用SomeClass'类型并将其传递给模板化的OtherClass,但由于存在许多实例,因此它非常繁琐;而且,我想假装两个班都不知道其他人的工作。:))

The question is simple: how can I use this syntax? 问题很简单:我该如何使用这种语法? (Without having to templatize OtherClass.) (无需模板化OtherClass。)

An obvious answer is that you could make SomeClass inherit from a non-template abstract class : 一个明显的答案是你可以使SomeClass继承自非模板抽象类:

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

And in turn, OtherClass will work on SomeAbstractBase : 而反过来, OtherClass将在SomeAbstractBase工作:

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

You're not really giving enough to say for sure that this in an appropriate solution, but it might be. 你并没有真正给予足够的肯定,在适当的解决方案中,但它可能是。 In the end, if you have no problem writing SomeAbstractBase (ie: you easily manage to identify what's common to all SomeClass<T> ), than it's probably the way to go. 最后,如果您在编写SomeAbstractBase没有问题(即:您很容易设法识别所有SomeClass<T>的共同点),那么可能就是这样。

You use type hiding: 您使用类型隐藏:

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

You will either need to templatize OtherClass -or- specialize the OtherClass constructor to accept the types of SomeClass you need to pass. 您将需要模板化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 ..)
}

It's not clear exactly what you're trying to do. 目前尚不清楚你正在尝试做什么。 But how about a templated constructor? 但是模板化的构造函数呢?

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

Of course this won't work if, for example, OtherClass needs a member of type SomeClass<T> . 当然,如果例如, OtherClass需要SomeClass<T>类型的成员,那么这将不起作用。

Use both compile-time (templates) and runtime polymorphism (virtuals): 使用编译时(模板)和运行时多态(虚拟):

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


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

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

OtherClass then takes a MyBase* and OtherClass::doSomethingWithSome invokes it virtual foo method. 然后, OtherClass接受一个MyBase*OtherClass::doSomethingWithSome调用它的虚拟foo方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM