我正在开发一个实现自己的迭代器的容器,我将其与 std::reverse_iterator<> 一起使用以获得反向迭代功能。我可以将反向迭代器分配给 rend 或 rbegin,但是当我尝试访问它的任何功能(例如 != 或 ==)时,我得到了这个:
1 IntelliSense: more than one operator "!=" matches these operands:
function template "bool std::operator!=(const std::reverse_iterator<_RanIt1> &_Left, const std::reverse_iterator<_RanIt2> &_Right)"
function template "bool avl::operator!=(const tree &left, const tree &right)"
operand types are: std::reverse_iterator<avl::avl_iterator<avl::avltree<char, int, std::less<char>, std::allocator<std::pair<const char, int>>>>> != std::reverse_iterator<avl::avl_iterator<avl::avltree<char, int, std::less<char>, std::allocator<std::pair<const char, int>>>>>
我的迭代器运算符重载:
bool operator == ( const avl_iterator& rhs ) const { return ( _node == rhs._node); }
bool operator != ( const avl_iterator& rhs ) const { return ( _node != rhs._node); }
以及我对反向迭代器的实现
typedef typename avl_iterator< tree > iterator;
typedef typename const_avl_iterator< tree > const_iterator;
typedef typename std::reverse_iterator<iterator> reverse_iterator;
typedef typename std::reverse_iterator<const_iterator> const_reverse_iterator;
和迭代器类型定义:
typedef typename tree::node node;
typedef typename tree::node_ptr node_ptr;
typedef typename tree::value_type* pointer;// for std reverse iterator
typedef typename tree::value_type& reference;
typedef typename tree::const_node_ptr const_node_ptr;
typedef typename tree::utilities utilities;
typedef typename tree::value_type value_type;
typedef std::bidirectional_iterator_tag iterator_category;
typedef std::ptrdiff_t difference_type;
我是如何使用运算符的
avltree<char,int> myTree;
myTree.insert(std::pair<char,int>('a',1));
myTree.insert(std::pair<char,int>('b',2));
myTree.insert(std::pair<char,int>('c',3));
avltree<char,int>::reverse_iterator rit = myTree.rbegin();
for(; rit != myTree.rend(); ++rit) //fails on this line
{
}
和迭代器类(const_iterator 是同一件事,但具有 const value_type)
template <class tree>
class avl_iterator {
public:
typedef typename tree::node node;
typedef typename tree::node_ptr node_ptr;
typedef typename tree::value_type* pointer;// for std reverse iterator
typedef typename tree::value_type& reference;
typedef typename tree::const_node_ptr const_node_ptr;
typedef typename tree::utilities utilities;
typedef typename tree::value_type value_type;
typedef std::bidirectional_iterator_tag iterator_category;
typedef std::ptrdiff_t difference_type;
private:
friend class const_avl_iterator<tree>;
node_ptr _node;
public:
avl_iterator() : _node() { }
avl_iterator( const node_ptr node ) : _node ( node ) { }
avl_iterator( const avl_iterator& iterator ) {
(*this) = iterator;
}
~avl_iterator() { _node = NULL; }
avl_iterator& operator=(const avl_iterator& rhs) {
_node = rhs._node;
return (*this);
}
avl_iterator& operator=(const const_avl_iterator<tree>& rhs) {
_node = rhs._node;
return (*this);
}
bool operator == ( const avl_iterator& rhs ) const { return ( _node == rhs._node); }
bool operator != ( const avl_iterator& rhs ) const { return ( _node != rhs._node); }
avl_iterator& operator++()
{
_node = utilities::next_node( _node );
return (*this);
}
avl_iterator operator ++( int ) {
avl_iterator temp(*this);
++(*this);
return(temp);
}
avl_iterator& operator -- () {
_node = utilities::prev_node( _node );
return (*this);
}
avl_iterator operator -- ( int ) {
avl_iterator temp(*this);
--(*this);
return(temp);
}
value_type& operator * () const {
assert( ! utilities::is_header( _node ) );
return _node->_value;
}
value_type* operator -> () const {
assert( ! utilities::is_header( _node ) );
return &_node->_value;
}
};
和树类:
template <
class Key,
class Type,
class Traits = std::less<Key>,
class Allocator = std::allocator<std::pair<Key const, Type>>
>
class avltree {
private:
typedef avltree< Key, Type, Traits, Allocator> tree;
public:
typedef std::pair<const Key, Type> value_type;
typedef Allocator allocator_type;
typedef typename allocator_type::size_type size_type;
typedef typename allocator_type::reference reference;
typedef Key key_type;
typedef Type mapped_type;
typedef Traits key_compare;
typedef typename avl_node< tree > node;
typedef typename node::node_ptr node_ptr;
typedef typename node::const_node_ptr const_node_ptr;
typedef typename avl_utilities< tree > utilities;
typedef typename avl_iterator< tree > iterator;
typedef typename const_avl_iterator< tree > const_iterator;
typedef typename std::reverse_iterator<iterator> reverse_iterator;
typedef typename std::reverse_iterator<const_iterator> const_reverse_iterator;
private:
node_ptr _header;
std::size_t _size;
key_compare _comparer;
allocator_type _alloc;
public:
//c'tors and d'tors
//*******************************************************
//Iterators
//*******************************************************
iterator begin() { return iterator( node::get_left( _header ) ); }
const_iterator begin() const { return const_iterator( node::get_left( _header ) ); }
const_iterator cbegin() const { return const_iterator( node::get_left( _header ) ); }
iterator end() { return iterator( _header ); }
const_iterator end() const { return const_iterator( _header ); }
const_iterator cend() const { return const_iterator( _header ); }
reverse_iterator rbegin() { return reverse_iterator( _header ); }
const_reverse_iterator rbegin() const { return const_reverse_iterator( _header ); }
const_reverse_iterator crbegin() const { return const_reverse_iterator( _header ); }
reverse_iterator rend() { return reverse_iterator( node::get_left( _header ) ); }
const_reverse_iterator rend() const { return const_reverse_iterator( node::get_left( _header ) ); }
const_reverse_iterator crend() const { return const_reverse_iterator( node::get_left( _header ) ); }
bool operator==(const tree& right)
{
if(_size != right.size())
{
return false;
}
const_iterator lhs = cbegin();
const_iterator rhs = right.cbegin();
while(lhs != cend() && rhs != right.cend() )
{
if(lhs->first != rhs->first || lhs->second != rhs->second)
{
return false;
}
++lhs;
++rhs;
}
return true;
}
bool operator!=(const tree& right)
{
return (!(*this == right));
}
bool operator<(const tree& right)
{
const_iterator lhs = cbegin();
const_iterator rhs = right.cbegin();
while(lhs != cend() && rhs != right.cend() )
{
if(lhs->first != rhs->first || lhs->second != rhs->second)
{
if(lhs->first < rhs->first || lhs->second < rhs->second)
{
return true;
}
}
++lhs;
++rhs;
}
return false;
}
bool operator>(const tree& right)
{
return ( right < *this );
}
bool operator<=(const tree& right)
{
return ( !(right < *this) );
}
bool operator>=(const tree& right)
{
return ( !(*this < right) );
}
};
//*******************************************************
//Relation Operators
//*******************************************************
template<class tree>
bool operator==(const tree& left,const tree& right)
{
if(left.size() != right.size())
{
return false;
}
tree::const_iterator lhs = left.cbegin();
tree::const_iterator rhs = right.cbegin();
while(lhs != left.cend() && rhs != right.cend() )
{
if(lhs->first != rhs->first || lhs->second != rhs->second)
{
return false;
}
++lhs;
++rhs;
}
return true;
}
template<class tree>
bool operator!=(const tree& left,const tree& right)
{
return (!(left == right));
}
template<class tree>
bool operator<(const tree& left,const tree& right)
{
tree::const_iterator lhs = left.cbegin();
tree::const_iterator rhs = right.cbegin();
while(lhs != left.cend() && rhs != right.cend() )
{
if(lhs->first != rhs->first || lhs->second != rhs->second)
{
if(lhs->first < rhs->first || lhs->second < rhs->second)
{
return true;
}
}
++lhs;
++rhs;
}
return false;
}
template<class tree>
bool operator>(const tree& left,const tree& right)
{
return ( right < left );
}
template<class tree>
bool operator<=(const tree& left,const tree& right)
{
return ( !(right < left) );
}
template<class tree>
bool operator>=(const tree& left,const tree& right)
{
return ( !(left < right) );
}
}//end namespace avl
最佳答案
在这一行:
rit != myTree.rend()
您正在比较两个类型的对象:
avltree<char,int>::reverse_iterator
它又是以下的别名:
std::reverse_iterator<avl_iterator<char, int>::iterator>
C++ 标准库在 std:: 命名空间中定义了一个模板化的 operator !=,它与反向迭代器的比较完全匹配(参见第 24.5 段的C++11 标准):
template <class Iterator1, class Iterator2>
bool operator!=(
const reverse_iterator<Iterator1>& x,
const reverse_iterator<Iterator2>& y)
但是,你也有这个:
template<class tree> bool operator!=(const tree& left,const tree& right)
由于模板是不受约束的(即使模板参数名为 tree,这并不意味着模板将只接受树),这也是一个完全匹配,但是模板化的 operator != 用于反向迭代器仍然更专业。
因此,调用应该不是有歧义的。我认为这是一个编译器错误。
要解决此问题,请确保树的不等运算符只接受树,无论如何这是个好主意(毕竟你真的不希望运算符比较任何):
template<class T> bool operator!=(const avltree<T>& left,const avltree<T>& right)
关于c++ - 运算符 != 对于 std::reverse_iterator c++ 是不明确的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15160276/
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
请帮助我理解范围运算符...和..之间的区别,作为Ruby中使用的“触发器”。这是PragmaticProgrammersguidetoRuby中的一个示例:a=(11..20).collect{|i|(i%4==0)..(i%3==0)?i:nil}返回:[nil,12,nil,nil,nil,16,17,18,nil,20]还有:a=(11..20).collect{|i|(i%4==0)...(i%3==0)?i:nil}返回:[nil,12,13,14,15,16,17,18,nil,20] 最佳答案 触发器(又名f/f)是
两者都可以defsetup(options={})options.reverse_merge:size=>25,:velocity=>10end和defsetup(options={}){:size=>25,:velocity=>10}.merge(options)end在方法的参数中分配默认值。问题是:哪个更好?您更愿意使用哪一个?在性能、代码可读性或其他方面有什么不同吗?编辑:我无意中添加了bang(!)...并不是要询问nobang方法与bang方法之间的区别 最佳答案 我倾向于使用reverse_merge方法:option
如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:
我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我
我明白了:x,(y,z)=1,*[2,3]x#=>1y#=>2z#=>nil我想知道为什么z的值为nil。 最佳答案 x,(y,z)=1,*[2,3]右侧的splat*是内联扩展的,所以它等同于:x,(y,z)=1,2,3左边带括号的列表被视为嵌套赋值,所以它等价于:x=1y,z=23被丢弃,而z被分配给nil。 关于ruby-带括号和splat运算符的并行赋值,我们在StackOverflow上找到一个类似的问题: https://stackoverflow
我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“
问题是:除了在“OperatorExpressions”?例如:1%!2 最佳答案 是的,可以创建自定义运算符,但有一些注意事项。Ruby本身并不直接支持它,但是superatorsgem做了一个巧妙的把戏,将运算符链接在一起。这允许您创建自己的运算符,但有一些限制:$geminstallsuperators19然后:require'superators19'classArraysuperator"%~"do|operand|"#{self}percent-tilde#{operand}"endendputs[1]%~[2]#Out
有没有办法让Ruby能够做这样的事情?classPlane@moved=0@x=0defx+=(v)#thisiserror@x+=v@moved+=1enddefto_s"moved#{@moved}times,currentxis#{@x}"endendplane=Plane.newplane.x+=5plane.x+=10putsplane.to_s#moved2times,currentxis15 最佳答案 您不能在Ruby中覆盖复合赋值运算符。任务在内部处理。您应该覆盖+,而不是+=。plane.a+=b与plane.a=
出于某种原因,heroku尝试要求dm-sqlite-adapter,即使它应该在这里使用Postgres。请注意,这发生在我打开任何URL时-而不是在gitpush本身期间。我构建了一个默认的Facebook应用程序。gem文件:source:gemcuttergem"foreman"gem"sinatra"gem"mogli"gem"json"gem"httparty"gem"thin"gem"data_mapper"gem"heroku"group:productiondogem"pg"gem"dm-postgres-adapter"endgroup:development,:t