Доступ к функции друга шаблона класса в main.

Мне трудно найти простое решение для этого. Я реализую дерево выражений, используя следующие классы, я объявляю функцию друга класса Tree. Моя проблема возникает, когда я пытаюсь запустить его в main.

template<class object> class Tree;
template<class object> Tree<object>::expTree(Tree<object> *&T);  // ERROR

template<class object>
struct Node
{
  object info;
  Node *next;
  Node<object>():info(0), next(NULL) {}
  Node<object>(const object &element, Node *n = NULL):
    info(element), next(n){}
};
template<class object>
class Stack
{
public:
  Stack();
  ~Stack();
  void makestackempty();
  bool stackEmpty() const;
  void push(object &item);
  void pop (object &item);
  void printStack() const;
private:
  Node<object> *top;
};
template<class object>
struct TreeNode
{
  object info;
  TreeNode *right;
  TreeNode *left;
  TreeNode()
  {}
};

template<class object>
class Tree
{
private:
  TreeNode<object> *root;
public:
  Tree();
  ~Tree();
  Tree(const Tree<object> &rhs);  // copy
  void operator=(const Tree<object> &rhs);
  void copyconst(TreeNode<object> *orig, TreeNode<object> *&rhs);
  void makeEmpty(TreeNode<object> *&tree);
  bool isEmpty()const;
  friend Tree<object> expTree(Tree<object> *&T){
    buildTree(T.root);
  };
  void buildTree(TreeNode<object> *&tree);
  void printTree(TreeNode<object> *&tree)const;
};

В основном я получаю «ошибка: expTree не был объявлен в этой области». Я также получаю «ошибка: ожидаемый конструктор, деструктор или преобразование типа перед токеном â; â» во второй строке этого кода. У кого-нибудь есть какие-либо указатели?


person stef0526    schedule 20.10.2011    source источник


Ответы (1)


template<class object> Tree<object>::expTree(Tree<object> *&T);  // ERROR
                     //^^^^^^^^^^^^^^ cause of the error

Этот шаблон функции на самом деле является бесплатной функцией и будет другом класса Tree. Так что это должно быть написано как:

template<class object> expTree(Tree<object> *&T); 

То есть убрать Tree<object>:: из объявления. Я только что понял, что в нем отсутствует тип возвращаемого значения, и я полагаю, вы имеете в виду, что Tree<object> является типом возвращаемого значения (а Tree<object>:: - это опечатка в вашем коде). Если да, то напишите это:

template<class object> Tree<object> expTree(Tree<object> *&T); 

Я хотел бы прокомментировать ваш стиль именования параметров и аргументов шаблона. Принято использовать T, U, V и т. д. для параметров шаблона, а не для аргумента функции. Так что приятно, когда вы пишете объявление как:

 template<class T> Tree<T> expTree(Tree<T> *&object);  

Ну, я просто поменял местами имена.

person Nawaz    schedule 20.10.2011
comment
Да, я понимаю название. Но у меня странный профессор. Ха-ха. Эта функция на самом деле возвращает void. поэтому я обновил эту строку на: template‹class object› void expTree(Tree‹object› *&T); и соответственно изменили другие декларации. Теперь я получаю сообщение об ошибке, что я не знаю, что это значит. :( _ В функции main': : undefined reference to void expTree‹std::basic_string‹char, std::char_traits‹char›, std::allocator‹char› › › (Tree‹std::basic_string‹char, std::char_traits‹char›, std::allocator‹char› › ›*&)' collect2: ld вернул 1 статус выхода _ - person stef0526; 20.10.2011
comment
Также обратите внимание, что встроенные функции друзей доступны только через ADL. Я не знаю, как это происходит, если есть предыдущее определение. - person K-ballo; 20.10.2011
comment
О вашей неопределенной ссылочной ошибке - вы не определили функцию expTree в любом месте, где компилятор/компоновщик может ее найти. - person j_kubik; 20.10.2011
comment
@ K-ballo Я пробовал несколько способов объявить эту функцию друга, но безуспешно. Возможно, это ошибка. Любые альтернативные способы инициализации этого? Мне нужно инициализировать построение дерева. Моя основная в настоящее время состоит из: Tree‹string› *T; cout ‹‹ Введите постфиксное выражение для преобразования: ‹‹ endl; expTree(*&T); - person stef0526; 20.10.2011
comment
@j_kubik Я безуспешно пытался объявить вне класса. Где бы вы предложили мне определить функцию? Или какие альтернативы? Как я могу инициализировать обычную функцию-член класса Tree в main? - person stef0526; 20.10.2011
comment
@ stef0526: Вы не должны писать expTree(*&T);. Вместо этого вы должны написать expTree(T);, так как вы уже определили T как Tree<string> *T; - person Nawaz; 20.10.2011
comment
Вы должны сделать это в заголовке - вы должны сделать это, как только все, что нужно для выполнения этой функции, уже объявлено - я думаю, сразу после того, как объявление класса дерева достаточно хорошо (если вы не используете материал, определенный позже в теле функции). курс). Если у вас все еще есть проблемы, опубликуйте больше кода. - person j_kubik; 22.10.2011