So I have been reading Programming Principles and Practices in C++
by Bjarne. And the section on conversion of templated objects of base/derived classes got me kinda confused. So I tried to try out different combinations and stumbled on something weird
#include <iostream>
class A {
public:
int i;
};
class B : public A {
int j;
};
template<typename T>
class Array_ref{
public:
Array_ref(T* pointer, int size) : p{pointer}, sz{size} {}
template<typename Q>
operator Array_ref<const Q>(){
static_cast<Q>(*static_cast<T*>(nullptr));
return Array_ref<const Q>{reinterpret_cast<Q*>(p), sz};
}
T& operator[](int n){
return p[n];
}
private:
T* p;
int sz;
};
void test_function(Array_ref<A* const> temp){
if(temp[0]->i)
std::cout<<"failed I guess"<<std::endl;
exit(0);
};
int main(){
B* testobj[1];
testobj[0] = new B;
testobj[0]->i = 0;
Array_ref<B*> a(testobj, 1);
test_function(a);
delete testobj[0];
exit(0);
}
The void test_function(Array_ref<A* const> temp)
is the line that troubled me. Since if I made it Array_ref<const A*>
it fails to compile with the error that it can't convert from B*
to const A*
, though as far as I know, I have provided the conversion rule which should fit the overloading arguments. In fact, aren't const A*
and A* const
very different things?
I would be glad if someone can help me out with where I am messing up, and what I missed out. Thanks a bunch!