I'm trying to implement an object to iterate easily an array, without static_cast each element separately (I have to do it hundreds of times). It works when I use the classic for loop, but when I attempt to use begin()/data()/end() it fails to compile. Do you know where is the mistake?
If I have these two classes:
struct Wrapper
{
int var1 = 0;
};
struct WrapperBig: public Wrapper
{
int var2 = 0;
};
And this is the object which will cast the pointers:
template <class T, int N>
class ArrayCasted final
{
public:
ArrayCasted(std::array<Wrapper*, N>& p): master(p) {}
// Works
int size() const {return static_cast<int>(master.size());}
inline T* operator[](const int index) {return static_cast<T*>(master[index]);}
// Fails
inline T* begin() const noexcept {return static_cast<T**>(master.begin());}
inline T* end() const noexcept {return static_cast<T**>(master.end());}
inline T* data() const noexcept {return static_cast<T**>(master.data());}
private:
std::array<Wrapper*, N>& master;
};
When I try to compile in Visual Studio 2019:
Wrapper* w1 = new Wrapper();
std::array<Wrapper*, 2> values {w1, w1};
ArrayCasted<WrapperBig, 2> casted {values};
// Works!
for (int i=0; i<casted.size(); ++i)
{
WrapperBig* current = casted[i];
current->var2 = -1;
}
// Fails :( C2440
for (WrapperBig* current : casted)
{
current->var2 = -1;
}
I tried the same with std::vector, but same problem. I think the mistake is in the begin/data/end functions, but I'm not sure why. I tried multiple things but everything fails.
How can I do this?
This code has a number of problems.
someArray.begin()is an iterator, which may be a pointer, but may instead be something else entirely, in which casting it to a pointer will completely fail.array<Wrapper *, 2>, you probably want the ArrayCasted to be to aarray<WrapperBig *, 2>.WrapperBig, you need to assure that what they point at are actuallyWrapperBigobjects.Putting those together we could get something on this order: