(与之前提到的unanswered question相关)。我想实现一个只能用相关类的向量作为参数调用的函数。
对于eq
如果我们有
class A;
class B: public A;
class C: public A;
class D
then it should be possible to call function with vector<A*>,vector<B*> or
vector <C*> but not vector <D*>
任何建议
答案 0 :(得分:1)
duck-typing对你来说足够好吗?考虑一下这段代码
template <class T>
void my_function (std::vector <T*> const &values) {
// Use features of A* here
}
如果使用指向T
的指针不支持的功能,则无法编译。通过使用A
的功能,我认为应该保证指向B
和C
的指针也能按预期工作。但是,可以使用D *
向量调用此函数,前提是D
的接口符合my_function
尝试执行的操作。
答案 1 :(得分:1)
我猜你已经尝试过创建像
这样的方法void doSomething(std::vector<A*>& things)
{
}
并尝试传递
std::vector<B*> bList = ...;
doSomething(bList);
正确?
为什么编译器会抱怨?因为没有意义。考虑doSomething()尝试执行
things.push_back(new C());
这不起作用,因为“事物”实际上是std::vector<B*>
。但是,如果它是std::vector<A*>
,则push_back将起作用。
那么我们可以从中学到什么呢?如果你只是从向量中读取,那么你所尝试的只是有意义,但是,向量不是只读容器。
一个简单的包装器显示了一个可能的解决方案(当然,包装器可以根据您的需要进行调整)。但是,我必须指出,使用虚拟方法可能会导致性能损失。
class A {};
class B : public A {};
template <class Base>
class AbstractVectorWrapper
{
public:
virtual size_t size() const = 0;
virtual Base* getElementAt(int index) const = 0;
};
template <class Base, class Derived>
class VectorWrapper : public AbstractVectorWrapper<Base>
{
private:
std::vector<Derived*> m_vector;
public:
explicit VectorWrapper(std::vector<Derived*> const& vector)
: m_vector(vector)
{
}
virtual size_t size() const
{
return m_vector.size();
}
virtual Base* getElementAt(int index) const
{
return m_vector[index];
}
};
void doSomething(AbstractVectorWrapper<A> const& wrapper)
{
for (size_t i=0;i<wrapper.size();i++)
{
A* a = wrapper.getElementAt(i);
}
}
int _tmain(int argc, _TCHAR* argv[])
{
std::vector<A*> as;
std::vector<B*> bs;
doSomething(VectorWrapper<A,B>(bs));
doSomething(VectorWrapper<A,A>(as));
return 0;
}