如何在C ++中区分数据结构模板和函数模板?

时间:2013-03-11 15:57:04

标签: c++ class templates data-structures function-templates

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

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 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:0)

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

对于所有意图和目的,classtypename在模板参数的情况下是可以互换的,这只是你选择做的风格问题[大多数人可能更喜欢你坚持一,不要混合两者 - 或者,当类型为“是”类时,可能使用class,而当它可以是“任何”类型时,可以使用typename

答案 2 :(得分:0)

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

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

typename的另一个用途是消除模板定义或声明中的依赖类型的歧义。

以下是wikipedia的示例:

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视为一种类型。

答案 3 :(得分:0)

只有一个位置不同(声明模板参数时),即使用模板模板时。

以下是定义明确的C ++

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

虽然不是这样:

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

由于您似乎刚刚开始使用C ++ /模板,这个角落的情况不会涉及到你一段时间:-)除了上面的类模板,函数模板,它没关系:typename和班级是同义词。