Страницы

Поиск по вопросам

суббота, 1 июня 2019 г.

Неявное приведение типов в параметризованных классах

template class B; template class A { public: friend class B; operator B (); }; template class B { public: B operator * (const B &s2) const {} friend class A; A operator [] (const B &s2) {} }; template A::operator B () { return B(); } int main() { B s1,s2,s3; s1[s2]*s3; // <-- ошибка }
[Error] no match for 'operator*' (operand types are 'A' and 'B')
Почему не работает оператор приведения?
UPD
Оказывается, вот это компилится
#include template class B; template std::ostream& operator << (std::ostream &os, const B &s) { } template class A { public: friend class B; operator B(); }; template class B { public: friend class A; A operator [] (const B &s2) {} friend std::ostream& operator << (std::ostream &, const B &); };
template B operator*(const A& s1, const B& s2) { return B(); }
template A::operator B() { return B(); }
int main() { B s1, s2, s3; std::cout << s1[s2] * s3; }
Так что, возможно, проблема с другим связана


Ответ

Вся проблема заключается в ADL (Argument Dependent Lookup), если же вы operator* реализуете отдельно от класса, то проблема будет решена:
template class B;
template class A { public: friend class B; operator B(); };
template class B { public: friend class A; A operator [] (const B &s2) { return A(); } };
template B operator*(const A& s1, const B& s2){ return B(); }
template A::operator B(){ return B(); }
int main() { B s1, s2, s3; s1[s2] * s3; }

Пояснение
Операторы, определенные в теле класса, не видны извне класса и могут быть найдены только при помощи ADL (поиска по типам аргументов).
Оператор приведения типа тут просто не успевает сработать, т.к. компилятор даже не знает что экземпляр класса A необходимо привести к классу B (да и вообще, какому-либо классу), а реализация данного оператора находится именно внутри класса B

Комментариев нет:

Отправить комментарий