首页 文章

模板中关键字'typename'和'class'的区别?

提问于
浏览
368

对于模板,我看到了两个声明:

template < typename T >
template < class T >

有什么不同?

这些关键字在下面的例子中究竟是什么意思(取自德国维基百科有关模板的文章)?

template < template < typename, typename > class Container, typename Type >
class Example
{
     Container< Type, std::allocator < Type > > baz;
};

5 回答

  • 5

    在指定模板的基本情况下, typenameclass 是可互换的:

    template<class T>
    class Foo
    {
    };
    

    template<typename T>
    class Foo
    {
    };
    

    是等价的 .

    话虽如此,有些特定情况下 typenameclass 之间存在差异 .

    第一个是依赖类型的情况 . typename 用于在引用依赖于另一个模板参数的嵌套类型时声明,例如本例中的 typedef

    template<typename param_t>
    class Foo
    {
        typedef typename param_t::baz sub_t;
    };
    

    你在问题中实际显示的第二个,尽管你可能没有意识到:

    template < template < typename, typename > class Container, typename Type >
    

    指定 template template 时,必须按上述方式使用 class 关键字 - 在这种情况下 not 可与 typename 互换(注意:因为在这种情况下C17允许两个关键字) .

    在显式实例化模板时,您还必须使用 class

    template class Foo<int>;
    

    我确信还有其他一些我错过的情况,但最重要的是:这两个关键字并不相同,而且这些是您需要使用其中一个的常见情况 .

  • 3

    虽然没有技术差异,但我看到这两个用来表示略有不同的东西 .

    对于应接受任何类型为T的模板,包括内置函数(如数组)

    template<typename T>
    class Foo { ... }
    

    对于仅在T是真实类的情况下才能工作的模板 .

    template<class T>
    class Foo { ... }
    

    但请记住,这纯粹是一些人使用的风格 . 不是由标准强制要求或由编译器强制执行

  • 18

    这段片段来自c入门书 . 虽然我确信这是错的 .

    每个类型参数必须以关键字class或typename开头:

    // error: must precede U with either typename or class
    template <typename T, U> T calc(const T&, const U&);
    

    这些关键字具有相同的含义,可以在模板参数列表中互换使用 . 模板参数列表可以使用两个关键字:

    // ok: no distinction between typename and class in a template parameter list
    template <typename T, class U> calc (const T&, const U&);
    

    使用关键字typename而不是class来指定模板类型参数似乎更直观 . 毕竟,我们可以使用内置(非类)类型作为模板类型参数 . 此外,typename更清楚地表明后面的名称是类型名称 . 但是,在模板已广泛使用后,typename被添加到C中;一些程序员继续专门使用类

  • 73
    • 没有区别

    • 模板类型参数 Container 本身就是一个带有两个类型参数的模板 .

  • 314

    对于命名模板参数, typenameclass 是等效的 . §14.1.2:

    template-parameter中的class和typename之间没有语义差异 .

    typename 但是在使用模板时可能在另一个上下文中 - 暗示您指的是依赖类型的编译器 . §14.6.2:

    模板声明或定义中使用的名称取决于模板参数,假定不命名类型,除非适用的名称查找找到类型名称或名称由关键字typename限定 .

    例:

    typename some_template<T>::some_type
    

    如果没有 typename ,编译器通常无法判断您是否引用了类型 .

相关问题