Здравствуйте, я немного запутался с шаблонами и надеюсь на вашу помощь.
Собственно вопрос таков. Почему компилятор C++ "не видит" шаблонизированное определение оператора присваивания (вероятно, это более общая проблема, просто я с ней столкнулся именно при использовании оператора присваивания) и продолжает использовать присваивание по-умолчанию? Для демонстрации сего феномена предлагаю такой пример:
#include <iostream>
class Circle {};
template <class Kind> struct Shape {};
template <>
struct Shape<Circle>
{
template <class Kind>
const Shape<Circle> &operator =
(const Shape<Kind> &Object)
{
std::cout << "Assignment.";
return *this;
}
/*
** const Shape<Circle> &operator =
** (const Shape<Circle> &Object)
** {
** return operator=<Circle>(Object);
** }
*/
};
int main()
{
Shape<Circle> FirstObject, SecondObject;
FirstObject=SecondObject;
return 0;
}
Эта программка печатает слово "Assignment" (т.е., использует переопределенный оператор присваивания) только если раскомментировать закомментированный фрагмент кода (т.е., если "специализировать" оператор присваивания). Объясните пожалуйста, почему так происходит и что мешает компилятору сделать подстановку шаблонных параметров самостоятельно? Если не затруднит, укажите соответствующие пункты стандарта. Спасибо.
Post scriptum. Может быть это как-то связано с предсказанием бесконечных рекурсий при раскрытии шаблонов? Дело в том, что шаблонизированный оператор присваивания прекрасно работает без вспомогательной перегруженной версии если тип его аргумента отличен от класса, для которого этот оператор определен. Например, следующий код работает как надо (с выполнением переопределенного оператора присваивания и выводом слова "Assignment"):
#include <iostream>
#include <list>
class Circle {};
template <class Kind> struct Shape {};
template <>
struct Shape<Circle>
{
template <class Kind>
const Shape<Circle> &operator =
(const std::list<Kind> &Object)
{
std::cout << "Assignment.";
return *this;
}
};
int main()
{
Shape<Circle> FirstObject;
std::list<Circle> SecondObject;
FirstObject=SecondObject;
return 0;
}