2010-12-21 136 views
3

我有两个类,我们称它们为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,但由于存在很多实例,它的工作非常乏味;而且,我想假装这两个类都不知道:))

问题很简单:我怎样才能使用这个语法? (不需要templatize OtherClass。)

回答

1

您将需要templatize 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 ..) 
} 
+0

专业为每一个类型似乎是一个好主意,因为:)幸好有没有这么多的类型,我会使用。 – 2010-12-21 23:09:52

0

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

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

当然,如果,例如,需要OtherClassSomeClass<T>类型的成员,这将无法工作。

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>的共同点),这可能是一条可行的路。

+0

嗯,是的,我想我可能已经忘记了使用继承,我现在觉得很愚蠢:( - 谢谢!:) – 2010-12-21 23:06:35

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

2

您可以使用隐藏型:

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

`impl`应该从`impl_base`继承。 - 另外,不幸的是,它不可能完全从用户隐藏模板类(`OtherClass`的实现必须完全在头部中)? – UncleBens 2010-12-21 20:00:59

相关问题