Оператор присваивания C ++ - PullRequest
1 голос
/ 23 октября 2011

Я пытаюсь реализовать оператор присваивания, но продолжаю получать сообщения об ошибках:

calendar.cpp:25: error: prototype for ‘lab2::Calendar<T>& lab2::Calendar<T>::operator=(lab2::Calendar<K>)’ does not match any in class ‘lab2::Calendar<T>’
calendar.h:19: error: candidate is: template<class T> template<class K> lab2::Calendar& lab2::Calendar::operator=(lab2::Calendar<K>)
make: *** [calendar.o] Error 1

Я также сталкивался с expected constructor, destructor, or type conversion before '&', когда пробовал разные решения.

Календарь имеет тип даты T, то есть даты внутри календаря могут отличаться от григорианских. Но я также хочу иметь возможность назначать календарь из календаря с другим типом даты.

Вот мое заявление и реализация.

//calendar.h
template <typename T>
class calendar {
//...
template <typename K> Calendar& operator=(const Calendar<K> c_other);
//...
}

//calendar.cpp
//...
template <typename T, typename K>
Calendar<T>& Calendar<T>::operator=(const Calendar<K> c_other) {};
//...

Буду признателен за любую помощь.

Ответы [ 4 ]

2 голосов
/ 23 октября 2011

Боюсь, что есть некоторые проблемы с использованием шаблонов.Для начала вы хотите использовать передачу ссылок, а не значение.Таким образом, вы можете создать объект параметра.

template <typename K> Calendar& operator=(const Calendar<K>& c_other);

Тогда возникает реальная проблема:

template <typename T, typename K>
Calendar<T>& Calendar<T>::operator=(const Calendar<K>& c_other) {};

Это в исходном файле, поэтому остальная часть кода не найдет специализацию.Вам следует перенести реализацию метода в файл заголовка, чтобы все вызывающие сайты могли подставлять свои собственные параметры шаблона и специализировать класс и оператор присваивания.

1 голос
/ 23 октября 2011

Помимо того, что сказали другие, правильный синтаксис для определения шаблона функции-члена шаблона класса:

template <typename T>
template <typename K>
Calendar<T>& Calendar<T>::operator=(const Calendar<K>& c_other)
{
    // your code here
}
1 голос
/ 23 октября 2011

Переместить тело (реализацию) вашего operator= в .h файла.

Поскольку шаблоны компилируются при необходимости, это накладывает ограничение для многофайловых проектов:реализация (определение) шаблонного класса или функции должна находиться в том же файле , что и его объявление.Это означает, что мы не можем разделить интерфейс в отдельном заголовочном файле и что мы должны включить и интерфейс, и реализацию в любой файл, который использует шаблоны.

Дополнительная информация здесь .

ОБНОВЛЕНИЕ: Если иногда некоторые объявления работают, когда они объявлены в исходном файле, убедитесь, что все объекты этого класса находятся в один и тот же исходный файл одна и та же единица перевода.

0 голосов
/ 23 октября 2011
template<class T>
class Calendar
{
public:
    T i;
    Calendar(const T & i_in):i(i_in){}
    template <class T2>
    Calendar <T>& operator=(const Calendar<T2> &);
};

template <class T>
 template <class T2>
Calendar<T>& Calendar<T>::operator=(const Calendar<T2>& t2)
{
 if (this == (void*) &t2) //avoid self assignment
  return *this; 

 this->i = t2.i; //implicit conversion here for example double to int or vice versa
 return *this;  
}

Учитывайте этот код.Я называю это асимметричным оператором присваивания, поскольку аргументы шаблона различны.Если неявное преобразование не существует, вам придется выполнить преобразование самостоятельно.Вы можете попробовать это с этим кодом:

int main() {
    Calendar<double> tmp(2.0);
    std::cout << "Tmp i : " << tmp.i << std::endl;
    Calendar<int> tmp_2(1);
    std::cout << "tmp_2 i : " << tmp_2.i << std::endl;
    tmp = tmp_2;
    std::cout << "Tmp i : " << tmp.i << std::endl;
    return 0;
}
...