我的问题涉及如何重用代码,对于算法,const
不知道(可以与常量或可变对象一起使用)?
我们以std::vector
迭代器为例
有两个迭代器类共享类似的方法:std::vector::iterator
和std::vector::const_iterator
。
两个迭代器都指向向量中或向量外的插槽(例如std::vector::end()
)。
他们都有增量和减量方法。
主要区别在于const_iterator
不能用于写入向量。
如果我正在为迭代器编写代码,我怎么能拥有不依赖于访问操作常量的iterator
和const_iterator
共享方法?
在我目前的代码中,由于可访问性的不同,我正在复制for_each
和visit
方法的代码。 for_each
循环是相同的for
循环,区别在于应用const_visitor而另一个应用mutable_visitor。
struct Object;
struct Const_Visitor
{
// Visit function cannot modified the given object.
virtual void visit(const Object& o) = 0;
};
struct Mutable_Visitor
{
// The visit function may modify the given object;
virtual void visit(Object& o) = 0;
};
struct Container
{
const unsigned int LIMIT = 16;
Object obj_container[LIMIT];
// Apply the read-only (constant) visitor
// to each object in the container
void for_each(Const_Visitor& cv) const
{
// Note: this loop management is the same
// as the loop management for the mutable for_each() method.
for (unsigned int i = 0; i < LIMIT; ++i)
{
cv.visit(obj_container[i]);
}
}
// Apply the read/write (mutable) visitor
// to each object in the container.
void for_each(Mutable_Visitor& mv)
{
// Note: this loop management is the same
// as the loop management for the const for_each() method.
for (unsigned int i = 0; i < LIMIT; ++i)
{
mv.visit(obj_container[i]);
}
}
};
在上面的示例中,两个for_each
函数的机制相同。只有访客更改。数组中的相同插槽将传递给visit
函数。
使用一个带有两个visit
方法的访问者可以稍微改变一下,但基本问题仍然存在。
struct Object;
struct Single_Visitor
{
// Method can't modify the object.
virtual void visit(const Object& o) = 0;
// Method may modify the object.
virtual void visit(Object& o) = 0;
};
struct Container
{
const unsigned int LIMIT = 16;
Object obj_container[LIMIT];
// Apply a visitor to each item in container.
void for_each(Single_Visitor& sv) const
{
for (unsigned int i; i < LIMIT; ++i)
{
// Should call the visit method,
// constant object.
sv.visit(obj_container[i]);
}
}
// Apply a visitor to each item in container.
void for_each(Single_Visitor& sv)
{
for (unsigned int i; i < LIMIT; ++i)
{
// Should call the visit method,
// mutable object.
sv.visit(obj_container[i]);
}
}
};
对于具有两个方法(相对于两个单独的类)的访问者类,容器的for_each
方法仍然具有相同的机制。循环是相同的,只是调用一个不同的方法。
那么,有没有办法让一个for_each
循环在const-ness上调用适当的访问者基础?
答案 0 :(得分:1)
不可能有一个可以作为const或非const的非静态成员函数。相反,您可以使用非成员或静态函数模板,并将容器作为参数传递。
struct Container
{
Object obj_container[LIMIT];
// C can match either `const Container` or `Container`
// V can match either `Const_Visitor` or `Mutable_Visitor`
template<class C, class V>
static void for_each(C& c, V& v) {
for (unsigned int i = 0; i < LIMIT; ++i)
{
v.visit(c.obj_container[i]);
}
}
void for_each(Const_Visitor& cv) const
{
for_each(*this, cv);
}
void for_each(Mutable_Visitor& mv)
{
for_each(*this, mv);
}
};