首页 文章

使用'class'或'typename'作为模板参数? [重复]

提问于
浏览
536

可能重复:模板中关键字'typename'和'class'的C差异

在C中定义函数模板或类模板时,可以这样写:

template <class T> ...

或者可以写这个:

template <typename T> ...

是否有充分的理由选择一个而不是另一个?


我接受了最受欢迎(也很有趣)的答案,但真正的答案似乎是“不,没有理由更喜欢一个而不是另一个 . ”

  • 它们是等价的(除非如下所述) .

  • 有些人有理由一直使用 typename .

  • 有些人有理由一直使用 class .

  • 有些人有理由同时使用这两种方法 .

  • 有些人不关心他们使用哪一个 .

但请注意,在模板模板参数的情况下,需要使用 class 而不是 typename . 见下面的user1428839's answer . (但这个特殊情况不是偏好问题,而是语言的要求 . )(这也将随 c++17 而改变)

10 回答

  • 140

    有区别,你应该更喜欢class to typename .

    但为什么呢?

    typename 对于模板模板参数是非法的,因此为了保持一致,您应该使用 class

    template<template<class> typename MyTemplate, class Bar> class Foo { };    //  :(
    template<template<class>    class MyTemplate, class Bar> class Foo { };    //  :)
    
  • 13

    根据Scott Myers,Effective C(第3版)第42项(当然必须是最终答案) - 差异是“没有” .

    建议是使用“class”如果预期T将永远是一个类,如果可能需要其他类型(int,char *,则为“typename”) . 考虑一下使用提示 .

  • -2

    Stan Lippman谈到了这一点here . 我觉得这很有趣 .

    简介:Stroustrup最初使用 class 指定模板中的类型以避免引入新关键字 . 委员会中的一些人担心这种关键字的重载导致了混乱 . 后来,委员会引入了一个新的关键字 typename 来解决语法歧义,并决定让它也用于指定模板类型以减少混淆,但为了向后兼容, class 保持其重载意义 .

  • 9

    它根本不重要,但是类让它看起来像T只能是一个类,而它当然可以是任何类型 . 所以typename更准确 . 另一方面,大多数人使用类,因此通常更容易阅读 .

  • 9

    为了回应Mike B,我更喜欢使用'class',因为在模板中,'typename'具有重载含义,但'class'没有 . 取这个选中的整数类型示例:

    template <class IntegerType>
    class smart_integer {
    public: 
        typedef integer_traits<Integer> traits;
        IntegerType operator+=(IntegerType value){
            typedef typename traits::larger_integer_t larger_t;
            larger_t interm = larger_t(myValue) + larger_t(value); 
            if(interm > traits::max() || interm < traits::min())
                throw overflow();
            myValue = IntegerType(interm);
        }
    }
    

    larger_integer_t 是一个从属名称,所以它需要'typename'在它之前,以便解析器可以识别 larger_integer_t 是一个类型 . 另一方面, class 没有这样的超载意义 .

    那......或者我只是懒惰 . 我输入'class'比'typename'更频繁,因此更容易输入 . 或者它可能是我写了太多OO代码的标志 .

  • 287

    扩展DarenW的评论 .

    一旦不接受typename和class非常不同,对它们的使用严格可能仍然有效 . 仅在实际上是类时才使用类,在基本类型时使用typename,例如 char .

    这些类型确实也被接受而不是 typename

    template <char myc ='/'>

    在这种情况下,甚至优于typename或class .

    想想其他人的“暗示”或可理解性 . 并且实际上认为第三方软件/脚本可能会尝试使用代码/信息来猜测模板发生了什么(考虑swig) .

  • 7

    只是纯粹的历史 . Quote from Stan Lippman

    这两个关键字的原因是历史性的 . 在原始模板规范中,Stroustrup重用现有的class关键字来指定类型参数,而不是引入可能会破坏现有程序的新关键字 . 这不是一个新的关键词没有被考虑 - 只是因为它可能被破坏而被认为是不必要的 . 直到ISO-C标准,这是声明类型参数的唯一方法 .

    但是应该使用 typename 而不是 class !有关详细信息,请参阅链接,但请考虑以下代码:

    template <class T>
    class Demonstration { 
    public:
    void method() {
       T::A *aObj; // oops ...
    };
    
  • 45

    作为上述所有帖子的补充,在处理模板模板参数时,强制使用 class 关键字(最多包括C14),例如:

    template <template <typename, typename> class Container, typename Type>
    class MyContainer: public Container<Type, std::allocator<Type>>
    { /*...*/ };
    

    在此示例中, typename Container 会生成编译器错误,如下所示:

    error: expected 'class' before 'Container'
    
  • 367

    我更喜欢使用typename,因为我不喜欢重载关键字(jeez - static 对于各种不同的上下文有多少不同的含义?) .

  • 1

    据我所知,你使用哪一个并不重要 . 它们在编译器的眼中是等价的 . 使用您喜欢的任何一种 . 我通常上课 .

相关问题