Как различить шаблон структуры данных и шаблон функции в C ++?

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

template<typename T>
struct X {
T weight;
int age;
};

Функции также могут использовать шаблоны следующим образом:

template <class T>
T func_name(int age, T human) {
something_here;
}

Одно из отличий s в том, что в первом случае мы используем typename в то время как во втором случае мы используем class,

Я нашел код, который содержит следующее:

template<typename S, typename T>
bool is_null(const row<T>& r)

Итак, я не могу понять, почему мы используем typename (и не class) в сочетании с функциями. Разве мы не должны использовать class?

1

Решение

В этом контексте нет технической разницы между ключевым словом typename и ключевое слово class, Это просто вопрос стиля. Смысл ваших первых двух примеров кода не изменится ни на один бит, если они начнутся с template<class T> struct X а также template <typename T> T func_name(int age, T human), (Я склонен использовать class когда я имею в виду, что параметр шаблона должен быть классом, а не чем-то вроде int.)

3

Другие решения

когда template был впервые представлен, разрешено только существующее ключевое слово class в качестве индикатора «это аргумент шаблона». Поскольку это становится довольно глупым, когда аргумент шаблона на самом деле не является классом (указатель на функцию, целочисленный тип или какой-либо другой тип «не класс»), typename был введен, чтобы сделать более ясным, что template<typename T> struct something { T x; }; позволяет something<int> a; так же как something<name_of_class> a;,

Для всех намерений и целей, class а также typename в случае шаблонов параметры являются взаимозаменяемыми, и это просто вопрос стиля, который вы выбираете делать [большинство людей, вероятно, предпочитают, если вы придерживаетесь одного, не смешивая два — или, возможно, используйте class когда тип ДОЛЖЕН быть классом, и typename когда это может быть «любой» тип].

0

В контексте определения параметров шаблона ключевые слова typename а также class являются синонимами.

Почти у каждого есть соглашение, которое они имеют тенденцию придерживаться. Я лично предпочитаю всегда использовать class здесь и зарезервировать typename Ключевое слово для его другого использования.

Другое использование для typename является устранение неоднозначности зависимого типа в определении или объявлении шаблона.

Вот пример из википедия:

template <typename T>
void foo(const T& t)
{
// declares a pointer to an object of type T::bar
T::bar * p;
}

struct StructWithBarAsType {
typedef int bar;
};

int main() {
StructWithBarAsType x;
foo(x);
}

Если вы внимательно посмотрите, вы заметите в строке T::bar * p;, bar зависит от параметра шаблона T что неоднозначно для компилятора как bar может быть типом или значением в зависимости от контекста типа T используется для создания шаблона. По умолчанию лечить bar в качестве значения, поэтому смысл будет умножать T::bar от p что не то, что мы хотим.

Решение состоит в том, чтобы квалифицировать зависимый тип с typename ключевое слово.

typename T::bar * p;

Это предупреждает компилятор о том, что мы намерены лечить bar как тип.

0

Есть только одно место, где они отличаются (при объявлении параметров шаблона), и это при использовании шаблона-шаблона.

Ниже четко определен C ++

template <template <typename> class TT> struct example_one {};

пока это не

template <template <typename> typename TT> struct example_two {};

Так как кажется, что вы только начинаете с C ++ / templates, этот угловой случай не будет вас беспокоить некоторое время 🙂 Помимо вышесказанного, шаблон класса, шаблон функции не имеет значения: typename и class синонимы.

0
По вопросам рекламы [email protected]