Jos*_*ver 4 c++ stl casting const
我有一个这样的课:
template<class T>
class AdjacencyList {
public:
void delete_node(const T&);
protected:
const typename std::vector<T>::const_iterator _iterator_for_node(
const std::vector<T>&, const T&
);
};
template<class T>
void AdjacencyList<T>::delete_node(const T& node) {
_nodes.erase(_iterator_for_node(_nodes, node));
}
template<class T>
const typename std::vector<T>::const_iterator AdjacencyList<T>::_iterator_for_node(
const std::vector<T>& list, const T& node
) {
typename std::vector<T>::const_iterator iter =
std::find(list.begin(), list.end(), node);
if (iter != list.end())
return iter;
throw NoSuchNodeException();
}
Run Code Online (Sandbox Code Playgroud)
显然,std::vector::erase()
不能拿一个const_iterator
,但std::find()
需要一个.我可以抛弃它在const
返回std::find()
时返回的迭代器的性能std::vector::erase()
,但有效的C++教会我const_cast
怀疑.
还有另一种方法吗?我无法相信从向量中移除元素这一常见的东西应该需要类型体操.:)
我建议你改变或重载你的_iterator_for_node()
函数来接受对列表的非const引用.究其原因std::find
返回const_iterator
是因为列表本身const
,因此begin()
并end()
返回const_iterator
秒.
顺便说一句,const_cast<>
实际上并不会转换const_iterator
成iterator
的"常量"只是名称的一部分,而不是一个CV-预选赛.
此外,从技术上讲,您不应该使用下划线为名称添加前缀,因为这是为实现保留的.(它通常会在实践中工作)
除了我对代码的直接修改,这里有一个想法:
代替一个成员函数的_iterator_for_node
其
我建议改为创建以下静态(全局/命名空间)函数:
template<class It, class T>
It checked_find(It begin, It end, const T& node)
{
It iter = std::find(begin, end, node);
if (iter != end)
return iter;
throw NoSuchNodeException();
}
Run Code Online (Sandbox Code Playgroud)
它将适用于任何迭代器类型(包括非STL,输入流迭代器,仅转发,const,反向迭代器......你的名字),它不需要显式区分const /非const版本:)
您的代码示例的工作版本只会读取
template<class T>
class AdjacencyList {
std::vector<T> _nodes;
public:
void delete_node(const T& node)
{ _nodes.erase(checked_find(_nodes.begin(), _nodes.end(), node)); }
};
Run Code Online (Sandbox Code Playgroud)
请注意代码减少.总是好兆头
干杯