Вам нужно потратить недели, чтобы больше узнать о C ++. Помните, C ++ - очень сложный язык программирования (даже с 5 годами практики вы не будете экспертом в C ++; я пишу код на C ++, но я не эксперт в этом; эксперты C ++ возможно только несколько десятков только на Земле). И не изучайте ничего старше, чем C ++ 11 и предпочтительно C ++ 17 (поскольку мы находимся в 2019 году, поэтому самый последний компилятор C ++ уже совместим с C ++ 17, и все они принимают C ++ 11; если ваш компилятор не знает о C ++ 11, обновите ваш компилятор C ++).
(если вам необходимо кодировать в C ++ 03 или более раннем C ++ вместо C ++ 11, попросите повышение заработной платы, потому что тогда вы используете устаревшие инструменты. Сегодня, в 2019 году, кодирование на C ++ 03 похоже на кодирование на COBOL : ему нужен редкий навык, имеющий денежную ценность.)
Итак, во-первых, прочитайте хорошую книгу по C ++ , такую как Программирование - Принципы и практика использования C ++ (разработчик C ++). Затем загляните на какой-нибудь C ++ справочный сайт. Читайте также как отлаживать небольшие программы (очень актуально здесь).
Затем скомпилировать все предупреждения и отладочную информацию . Если ваш компилятор GCC , скомпилируйте как минимум с g++ -Wall -g
. Вы получите хорошее диагностическое сообщение. Покажите это в вашем вопросе, пожалуйста .
Наконец, вы объявили свой inorder
как принимающий один аргумент, и вы не даете ни одного при вызове этого (и при этом вы не согласны):
tree.inorder();
// ^ missing argument
Вы ошибочно спросили:
Я создаю класс шаблона двоичного дерева поиска и хочу использовать указатели на функции
Как я уже говорил, вам следует избегать указателей на функции (они так похожи на C, а не на подлинный C ++) и использовать некоторые std::function
type в объявление этого inorder
и передать, возможно, некоторое анонимное лямбда-выражение на сайте вызова . Потому что то, что вы должны передать концептуально, это не указатель на функцию, а замыкание (которое объединяет необработанный указатель функции с данными, закрытые значения) или, если вы, к сожалению, хотите избежать подлинный C ++ и совместимость с простым C процедурным программированием * стиль 1071 * и соглашения о вызовах , имеют обратные вызовы , поэтому передают не только необработанный указатель на функцию, но и некоторые данные клиента.
Итак, вы действительно хотите объявить и определить (как большинство C ++ контейнеров do)
template<class T>
inline void Bst<T>::inorder(std::function<void(T&)> fun) const;
(позже, как оптимизация , вы можете передать fun
как const
reference ) и использовать его (с лямбда-выражением), как, например, :
tree.inorder([](T& x) { std::cout << x << std::endl; });
Я утверждаю, что ваш учитель должен сначала научить вас замыканиям и тому, как их красиво использовать в каком-то стиле функционального программирования (что вполне естественно в вашем случае), а затем объяснить их реализацию 1095 * также и позже, обучая указателям на функции. В большинстве случаев указатели функций устарели в C ++ (но они существуют для совместимости с C и устаревшими версиями C ++).
PS. То, что вы не понимаете, занимает несколько десятков страниц для объяснения (поскольку система типов C ++ очень сложна). У нас не так много места здесь (и времени, чтобы написать это). Пожалуйста, уделите неделю чтению хорошей книги по C ++ .