В заголовке необходимо указать пространства имен.
В C ++,параметры (кроме массивов) всегда передаются как тип значения , если вы не укажете его, в отличие от Java, где все объекты передаются как ссылочный тип.Это означает, что если сигнатура функции printVector(std::vector<T> list)
, список будет скопирован при подаче в printVector
.Это часто нежелательно.Поэтому вам нужно изменить его так, чтобы он передавался по ссылке , добавив &
к типу:
template<typename T> void printVector(std::vector<T>& list);
// ^
, но сделав его ссылкой, означает изменение list
внутри printVector
будет распространяться.Вы часто не хотите случайно изменить список.Это может быть выполнено путем установки параметра const
ant:
template<typename T> void printVector(const std::vector<T>& list);
// ^^^^^
(Делая его константной ссылкой, также имеет то преимущество, что он может принимать значения r).
Также в отличие от Java, в C и C ++ #include
не знает, включали ли вы заголовок один раз.#include
- это просто механизм копирования и вставки.Это означает, что если каким-то образом компилятор увидит
#include "Sort_Search.h"
...
#include "Sort_Search.h"
, то будут определены 2 копии printVector
, что приведет к ошибке компилятора.Это возможно, если два разных заголовка a.h
и b.h
включают Sort_Search.h
, а некоторые исходные файлы включают в себя a.h
и b.h
.Чтобы избежать этого, мы всегда должны предоставлять и # include guard , который предотвращает включение файла более одного раза:
#ifndef SORT_SEARCH_H_m6f2kyhdncxflxr
#define SORT_SEARCH_H_m6f2kyhdncxflxr
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
template<typename T> void printVector(const std::vector<T>& list);
#endif
//^^^^
A vector<T>
не является встроенным типом, поэтому вам нужно #include <vector>
, чтобы компилятор знал о существовании такого типа.
#ifndef SORT_SEARCH_H_m6f2kyhdncxflxr
#define SORT_SEARCH_H_m6f2kyhdncxflxr
#include <vector>
//^^^^^^^^^^^^^^^
template<typename T> void printVector(const std::vector<T>& list);
#endif
Наконец, template реализован не так, как универсальные шаблоны в Java или C #.Это похоже на механизм копирования и вставки на уровне AST.Каждый раз, когда вы вызываете printVector
, компилятор определяет, что такое T
(скажем, int
), а затем создает новую функцию, заменяя каждый T
на int
.
Из-за этого реализация шаблона не может быть отделена от объявления.Или реализация является частью декларации .Поэтому, для правильности, printVector
необходимо переместить в заголовок:
#ifndef SORT_SEARCH_H_m6f2kyhdncxflxr
#define SORT_SEARCH_H_m6f2kyhdncxflxr
#include <vector>
#include <iostream>
template<typename T> void printVector(const std::vector<T>& list) {
for (int i = 0; i < list.size(); ++ i) { ... }
}
#endif
Или, если вы все еще хотите отделить .cpp
от .h
, вы можете включить.cpp
из .h
:
#ifndef SORT_SEARCH_H_m6f2kyhdncxflxr
#define SORT_SEARCH_H_m6f2kyhdncxflxr
#include <vector>
template<typename T> void printVector(const std::vector<T>& list);
#include "Sort_Search.cpp"
//^^^^^^^^^^^^^^^^^^^^^^^^
#endif
// Sort_Search.cpp:
#include <iostream>
template<typename T> void printVector(const std::vector<T>& list) {
...
}