Click here to Skip to main content
15,887,135 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I have Iterator template for class and class for use in the for statement.
C++
template<class T>
class Itr2 {
public:
	 Itr2()  { }
	~Itr2()  { }

	typedef typename Itr2 type;
	typedef typename T& reference;

	virtual type& operator++()						{ return *this; }
	virtual T&	  operator*()						{ return ((reference)*((type*)this)); }
	virtual bool  operator==(const type& o) const { return true; }
	virtual bool  operator!=(const type& o) const { return false; }
};


template<class T>
class I2
{
public:
	typedef I2<T> type;
	typedef T	  value;
	typedef T& reference;
	typedef typename Itr2<T> iterator;

	virtual iterator& begin() { return *(new iterator()); }
	virtual iterator& end()   { return *(new iterator()); }
};


Next, I created class for standard std::vector<>.
C++
template<class T>
class ItrSTD : public Itr2<T> {
public:
	typedef typename Itr2<T> base_type;
	typedef typename ItrSTD<T> type;
	typedef typename T& reference;
	typedef typename std::vector<T>::iterator std_itr;
protected:
	std_itr itr_;
public:
	ItrSTD(const type& o)								{ itr_ = o.itr_; }
	ItrSTD(const std_itr& o)							{ itr_ = o; }

	virtual base_type&  operator++()					{ itr_++; return *this; }

	virtual T&			operator*()						{ return ((reference)(*this->itr_)); }
	bool  operator==(const base_type& o) const override { return (((const type&)o).itr_ == this->itr_); }
	bool  operator!=(const base_type& o) const override { return (((const type&)o).itr_ != this->itr_); }
};



template<class T>
class VSTD : public I2<T> {
protected:
	std::vector<T>  arr_;
public:
	typedef typename ItrSTD<T>  iterator;

	VSTD(const VSTD& o)  { arr_ = o.arr_; }
	template<typename ...E>	VSTD(E&&...e) : arr_({ std::forward<T>(e)... }) {  }

	iterator& begin()  _NOEXCEPT  override{ return (*new iterator(arr_.begin())); }
	iterator& end()    _NOEXCEPT  override{ return (*new iterator(arr_.end())); }

};


If i use direct statement for(int i:v). It is works fine, but when I try to do this from the pointer compiler use base class operator!= (not override operator!=) and code doesn't work :(.

C++
int v_i = 0;
VSTD<int> vstd_a = { 1, 2, 3 };
I2<int> *i2 = &vstd_a;

for (int j : *i2) //DOESN't work :( use operator!= from base class
{
v_i += j;
}
for (int j : vstd_a) //work fine :)  use operator!= from VSTD.
{
 v_i += j;
}


Why this happen. It is possible to use for statement for template pointer ?
begin(), end() functions works fine. Only operator work different.
P.S. I use VS2013 compiler.


Some additional info:

If i simplify the code:

C++
template<typename T>
class I3
{
public:
	T i;
	virtual bool  operator==(const I3& o) const { return false; }
};

template<typename T>
class I3O : public I3<T>
{
public:
	virtual bool  operator==(const I3& o) const override { return true; }
};


Both result are fine (return true) and compare from override class (only for( : ) work bad :():

C++
I3O<int> i3_a, i3_b; I3<int> *i3_ap, *i3_bp;

i3_ap = &i3_a; i3_bp = &i3_b; bool i3_c;

i3_c = (i3_a == i3_b);
i3_c = ((*i3_ap) == (*i3_bp));
Posted
Updated 17-Nov-14 23:28pm
v4
Comments
KarstenK 18-Nov-14 3:35am    
shouldnt the override function also be virtual?
nashi 18-Nov-14 5:21am    
No, virtual means only that can be overriden within an inheriting class . If its final than i can remove virtual.

1 solution

Possibly because when you do this

C
for(int j : *i2)


there is a hidden cast to the type I2, so when the compiler looks for the vTable he gets the one of the base class.

That is, if you take a pointer of a child class and cast it to one of its fathers you get to use their exported vTable.

BTW this is a fairly recent C++ standard, isnt it? I'm stuck with C++/98 for the time being so I don't have first-hand experience on that kind of constructs, I am speculating on the basis of similar hand-crafted bugs (or features) I encountered.

Hope that helps,
Denis
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900