1

我了解到可以通过以下方式使用模板创建数据结构:

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

这些函数还可以通过以下方式使用模板:

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

不同之处之一是在第一种情况下我们使用typename,而在第二种情况下我们使用class

我发现包含以下内容的代码:

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

所以,我无法理解的是为什么我们将typename(而不是class)与函数结合使用。我们不应该使用class吗?

4

4 回答 4

3

typename在这种情况下,关键字和关键字之间没有技术差异class。这只是风格问题。template<class T> struct X如果它们以and开头,则前两个代码示例的含义不会改变template <typename T> T func_name(int age, T human)class(当我的意思是暗示模板参数应该是一个类而不是类似的东西时,我倾向于使用int。)

于 2013-03-11T16:00:15.020 回答
0

首次引入时template,它只允许现有关键字class作为指示符“这是一个模板参数”。由于当模板参数实际上不是一个类(函数指针、整数类型或其他一些“非类”类型)时,这变得相当愚蠢,所以typename引入 是为了更清楚地template<typename T> struct something { T x; };允许.something<int> a;something<name_of_class> a;

出于所有意图和目的,classtypename模板参数是可互换的情况下,这只是您选择做的样式问题[大多数人可能更喜欢如果您坚持一个,而不是混合两者 - 或者,也许class在type 必须是一个类,并且typename当它可以是“任何”类型时]。

于 2013-03-11T16:23:10.607 回答
0

在模板参数定义的上下文中,关键字typenameclass是同义词。

几乎每个人都有一个他们倾向于坚持的约定。我个人更喜欢始终class在此处使用并将typename关键字保留用于其他用途。

for 的另一个用途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其视为一种类型。

于 2013-03-11T16:23:39.727 回答
0

它们只有一处不同(声明模板参数时),那就是使用模板模板时。

以下是定义明确的C++

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

虽然这不是:

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

由于您似乎刚刚开始使用 C++/模板,因此暂时不会担心这种极端情况 :-) 除了上面的类模板、函数模板之外,没关系:typename 和 class 是同义词。

于 2013-03-11T17:52:17.420 回答