Consider the following piece of code:
template<class T>
class Me {
private:
T* data;
size_t size;
friend class Me<?????>;
public:
Me(size_t s) : data(new T[s]), size(s) {}
virtual ~Me() { delete [] data; }
Me<T> operator= (const Me<T const>& rhs) {
for(size_t i = 0; i < size; ++i)
data[i] = rhs.data[i]; // Gives compile error "data is a private member of Me<XX const>"
}
}
Disregarding that this is a very contrived example, what is the right way to access a private data member of a version of the class differing only by constness of T
? If it were going the other way, I could simply do: friend class Me<T const>;
I don't want to expose a way to access the internal data pointer to the broader world (even via getter) in my real code. Also, I'm not doing anything here that goes against const correctness, since I'll never modify the right-hand side of the equation.
Maybe this is totally all the wrong way to go about it, but it seems like a perfectly reasonable thing to do at the time.
Would the better thing to do be creating a free function? E.g.
template<class T>
Me<T> operator= (const Me<T>& lhs, const Me<T const>& rhs) {...}
This second approach compiles fine, but gives me a link (Undefined symbols) error that I'm still tracing down.
You need to define the assignment operator of the class and a templated one that work on Me<T const>
also give friendship to the no const version as:
template<class T>
class Me {
private:
friend class Me<std::remove_const_t<T>>;
public:
Me<T>& operator= (const Me<T>& rhs) {
// ...
return *this;
}
template <class U, std::enable_if_t<std::is_same_v<U, T const>, bool> = true>
Me<T>& operator=(Me<U> const& rhs) {
// ...
return *this;
}
};
Me<int> r;
Me<int const> l;
r = l;