[英]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.