I need help understanding GCC's problem with a templated-derived-structure.
The following is the basic content of a header file called Data.hpp:
template <typename T> struct DataContent {
T *ptr;
// more stuff would go here but has been commented out for debug
};
template <typename T> struct Data : DataContent<T> {
public:
uint_fast64_t N=0;
inline Data() {};
inline ~Data() { delete this->ptr; };
// ****************** PROBLEM METHOD LIVES HERE *******************
inline Data &operator= (const T &rhs) {
for (uint_fast32_t n=0; n<N; n++ ) this->ptr[n] = rhs;
return *this;
};
// ****************************************************************
// more stuff would go here but has been commented out for debug
};
template class Data<float>;
template class Data<Data<float>>;
The system is a Intel i5, and the build command is:
g++-4.9 -Wall -fexceptions -march=corei7-avx -Wnon-virtual-dtor -Wshadow -Winit-self -Wfloat-equal -Winline -Weffc++ -std=c++11 -masm=intel -g -mfma -march=corei7-avx -mavx -O3 -std=c++11 -masm=intel -g -c
The error I get is
Data.hpp error: use of deleted function ‘Data<float>& Data<float>::operator=(const Data<float>&)’
Data.hpp note: ‘Data<float>& Data<float>::operator=(const Data<float>&)’ is implicitly deleted because the default definition would be ill-formed:
Any of the following actions, by themselves, makes this error go away:
- Eliminating explicit instantiation
template class Data<Data<float>>
- Making Data a stand-alone structure, without use of the base structure DataContent
- Replacing, in the problem method,
this->ptr[n]=rhs
withthis->ptr[n]=0
(without changing the function declaration)
Knowing all this, I'm still confused about the source of the problem. Frankly, I just plain confused as to why it is even trying to use the function
Data<float>& Data<float>::operator=(const Data<float>&)
anyways. I agree with the compiler that it is "ill-formed", but why it is trying to use it in the first place!? I expect the following functions to be used
Data<float>& Data<float>::operator=(const float&)
Data<Data<float>>& Data<Data<float>>::operator=(const Data<float>&)
but not the one it is trying.
Equally important, it's confusing as to why fix #3 would help. Indeed, I would expect fix #3 to actually break the compilation when building the Data<Data<float>>
class instantance.
Can someone please help? (BTW, fixes 1-3 are not viable solutions for end goals)