2012-02-23 6 views
0

Хорошо, я немного застрял в попытке перегрузить оператор < < для моего класса шаблонов. Требование состоит в том, чтобы оператор < < должен вызывать функцию печати пустоты, определенную для этого класса.оператор << перегрузка для вызова функции функции печати

Вот важный материал из шаблона заголовка:

template <class T> 
class MyTemp { 
public: 
    MyTemp();   //constructor 

    friend std::ostream& operator<< (std::ostream& os, const MyTemp<T>& a); 

    void print(std::ostream& os, char ofc = ' ') const; 

и вот моя функция печати в основном это вектор и печатает последний элемент в первом:

template <class T> 
void Stack<T>::print(std::ostream& os, char ofc = ' ') const 
{ 
    for (int i = (fixstack.size()-1); i >= 0 ; --i) 
    { 
     os << fixstack[i] << ofc; 
    } 
} 

и вот как я у оператора < < перегруженный:

template <class T> 
std::ostream& operator<< (std::ostream& os, const Stack<T>& a) 
{ 
    // So here I need to call the a.print() function 
} 

Но я получаю ошибку «неразрешенный внешний символ». Так что я думаю, у меня есть две проблемы. Во-первых, это способ исправить ошибку выше. Во-вторых, как только это исправлено, я просто позвоню a.print (os) внутри < < перегрузка? Я знаю, что он должен вернуть обратно. Любая помощь будет принята с благодарностью!

+1

читайте этот файл: http://www.parashift.com/c++-faq/templates.html#faq-35.16 –

+0

Вы вызываете шаблон шаблона 'MyTemp' в первом фрагменте и' Stack' в других.Вы делаете это в своем реальном коде? –

ответ

2

Проще всего было бы оставить print общедоступным (как в вашем примере), поэтому оператору не обязательно быть другом.

template <class T> 
class MyTemp { 
public: 
    void print(std::ostream& os, char ofc = ' ') const; 
}; 

template <class T> 
std::ostream& operator<< (std::ostream& os, const MyTemp<T>& a) { 
    a.print(os); 
    return os; 
} 

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

// Declare the templates first 
template <class T> class MyTemp; 
template <class T> std::ostream& operator<< (std::ostream&, const MyTemp<T>&); 

template <class T> 
class MyTemp { 
public: 
    friend std::ostream& operator<< <>(std::ostream& os, const MyTemp<T>& a); 
    // With a template thingy here ^^ 

private: 
    void print(std::ostream& os, char ofc = ' ') const; 
}; 

template <class T> 
std::ostream& operator<< (std::ostream& os, const MyTemp<T>& a) { 
    a.print(os); 
    return os; 
} 

Или вы могли бы определить встроенный оператор:

template <class T> 
class MyTemp { 
public: 
    friend std::ostream& operator<<(std::ostream& os, const MyTemp<T>& a) { 
     a.print(os); 
     return os; 
    } 

private: 
    void print(std::ostream& os, char ofc = ' ') const; 
}; 

Для вашего последнего вопроса:

Во-вторых, как только это будет исправлено, я просто позвоню a.print(os) внутри << перегрузка? Я знаю, что ему нужно вернуть ostream.

Это действительно необходимо вернуть ostream - так что просто верните тот, который был передан, как в моем примере кода.

+0

Ах отлично работает! Необходимо работать над моими навыками. Я буду помнить эту информацию в будущем. – Doug

0

Поскольку ваша функция print является общедоступной, нет необходимости объявлять operator<< как friend.

Помните, что вы используете класс Stack ваша перегрузки и MyTemp выше ...

+0

Неплохо, что у меня это не было в моем коде, я пытался изменить все экземпляры Stack на MyTemp, когда я отправлял сообщения, чтобы избежать путаницы, пропустил этот. Спасибо хоть. – Doug

1

Эта ошибка означает, что есть символ, который не может быть признан linker.on каким переменным будут у получать это ошибка , а также проверить стек, так как существует класс std :: stack.

Смежные вопросы