Here the code that I a lot simplify for this question.
template<class T>
class A
{
public:
A<T>& operator=(A<T> const& other)
{
std::cout << "A<T>& operator=(A<T> const& other)\n";
return this->operator=(other.m_container);
}
template<class U>
A<T>& operator=(std::vector<U> const& other)
{
std::cout << "A<T>& operator=(std::vector<U> const& other)\n";
// Code not shown: m_container = other;
return *this;
}
A<T>& operator=(std::initializer_list<T> il)
{
std::cout << "A<T>& operator=(std::initializer_list<T> il)\n";
// Code not shown: m_container = il;
return *this;
}
std::vector<T> m_container;
};
//
template<typename T>
class B: public A<T>
{};
Initially I believed it was an issue with template but this does not change facts. So here the simplified classes for my question:
class AA
{
public:
AA& operator=(AA const& other)
{
std::cout << "AA& operator=(AA const& other)\n";
return this->operator=(other.m_container);
}
AA& operator=(std::vector<float> const& other)
{
std::cout << "AA& operator=(std::vector<float> const& other)\n";
// Code not shown: m_container = other;
return *this;
}
AA& operator=(std::initializer_list<float> il)
{
std::cout << "AA& operator=(std::initializer_list<float> il)\n";
// Code not shown: m_container = il;
return *this;
}
std::vector<float> m_container;
};
//
class BB: public AA
{};
My question is that I'm not totally sure to understand why:
BB bb1;
bb1 = { -1.0f, -1.0f, 0.0f };
is not compiling:
In function ‘int main()’:
error: no match for ‘operator=’ (operand types are ‘BB’ and ‘<brace-enclosed initializer list>’)
bb1 = { -1.0f, -1.0f, 0.0f };
^
note: candidate: ‘BB& BB::operator=(const BB&)’
BB& operator=(BB const& other)
^~~~~~~~
note: no known conversion for argument 1 from ‘<brace-enclosed initializer list>’ to ‘const BB&’
While the following modification, the code is working:
class BB: public AA
{
public:
BB& operator=(std::initializer_list<float> il)
{
std::cout << "BB& operator=(std::initializer_list<float> il)\n";
AA::operator=(il);
return *this;
}
};
Result:
BB& operator=(std::initializer_list<float> il)
AA& operator=(std::initializer_list<float> il)
This is particularly strange because the following code is not impacted (the inheritance is well called):
BB bb1;
BB bb2;
bb2 = bb1;
Result:
AA& operator=(AA const& other)
AA& operator=(std::vector<float> const& other)
So no need to change the class to:
class BB: public AA
{
public:
BB& operator=(BB const& other)
{
std::cout << "BB& operator=(BB const& other)\n";
AA::operator=(other.m_container);
return *this;
}
BB& operator=(std::initializer_list<float> il)
{
std::cout << "BB& operator=(std::initializer_list<float> il)\n";
AA::operator=(il);
return *this;
}
};
At first, I thought it was because I had to call base<T>::method()
from a template derived class that was why I had to create a derived<T>::method()
calling the base but this is not the reason. Ideally I would like avoiding creating BB& operator=(std::initializer_list<float> il)
that looks like a useless copy/past code to me.
Thanks in advance!
Aucun commentaire:
Enregistrer un commentaire