Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用';类别';或';typename';模板参数?_C++_Templates - Fatal编程技术网

C++ 使用';类别';或';typename';模板参数?

C++ 使用';类别';或';typename';模板参数?,c++,templates,C++,Templates,可能重复: 在C++中定义函数模板或类模板时,可以写如下: template <class T> ... template <typename T> ... 模板。。。 也可以这样写: template <class T> ... template <typename T> ... 模板。。。 是否有充分的理由选择其中一个而不是另一个 我接受了最受欢迎(也是最有趣)的答案,但真正的答案似乎是“不,没有理由选择其中一个。” 它们是等

可能重复:

<>在C++中定义函数模板或类模板时,可以写如下:

template <class T> ...
template <typename T> ...
模板。。。
也可以这样写:

template <class T> ...
template <typename T> ...
模板。。。
是否有充分的理由选择其中一个而不是另一个


我接受了最受欢迎(也是最有趣)的答案,但真正的答案似乎是“不,没有理由选择其中一个。”

  • 它们是等效的(除非下文另有说明)
  • 有些人有理由总是使用
    typename
  • 有些人有理由总是使用
    class
  • 有些人有理由两者兼用
  • 有些人不在乎他们用哪一个

但是,请注意,在C++17之前,对于模板参数,需要使用
class
而不是
typename
。见下文。(但这个特殊情况不是偏好的问题,而是语言的要求。)

据我所知,使用哪一种并不重要。在编译器看来,它们是等价的。你喜欢哪个就用哪个。我通常使用课堂。

斯坦·利普曼谈到了这一点。我觉得很有趣


摘要:Stroustrup最初使用
class
在模板中指定类型,以避免引入新关键字。委员会中的一些人担心这个关键词的过载会导致混乱。后来,委员会引入了一个新的关键字<代码>类型名>代码>来解决句法歧义,并决定让它也用于指定模板类型以减少混淆,但是为了向后兼容,<代码>类< /代码>保持其超载意义。< Scott Myers >,有效的C++(第三版)项目42。(当然,这必须是最终答案)——区别在于“没有”


忠告是使用“类”,如果预期T将永远是一个类,如果其他类型(int,char *什么)都可以被预期为“类型名”。请考虑它是一个用法提示。

< p>我喜欢使用类型名,因为我不是重载关键字的粉丝(Jez——<代码>静态< /代码>对于不同的上下文有多少不同的含义?).

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

作为回应,我更喜欢使用“类”,因为在模板中,“typename”具有重载含义,but“类”没有。以此选中整数类型为例:

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);
    }
}
模板
类智能整数{
公众:
typedef整数性状;
整数类型运算符+=(整数类型值){
typedef typename traits::更大的\u整数\u t更大的\u t;
较大的中间值=较大的中间值(myValue)+较大的中间值(value);
如果(interm>traits::max()| | interm
larger\u integer\u t
是一个依赖名称,因此它需要'typename'对其进行处理,以便解析器能够识别
larger\u integer\u t
是一个类型。class则没有这种重载含义


那……或者我只是内心懒惰。我键入“class”的频率远远高于键入“typename”,因此更容易键入。或者这可能是我编写了太多OO代码的迹象。

扩展了DarenW的评论

一旦typename和class被认为差别不大,严格使用它们可能仍然有效。仅当class确实是一个类时才使用class,当typename是基本类型时才使用typename,例如char

这些类型实际上也被接受,而不是typename

模板<charmyc='/'>

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

认为对他人来说是“丰满”或可理解的。实际上,第三方软件/脚本可能会尝试使用代码/信息来猜测模板发生了什么(考虑SWIG)。

< P>纯历史。 这两个关键字的原因是历史性的。在最初的模板规范中,Stroustrup重用了现有的class关键字来指定类型参数,而不是引入一个新的关键字,这当然可能会破坏现有的程序。这并不是说没有考虑一个新的关键字,只是考虑到它的特性,认为它没有必要在ISO-C++标准之前,这是声明类型参数的唯一方法

但是你应该使用类型名,而不是类! 有关更多信息,请参阅链接,但请考虑以下代码:

template <class T>
class Demonstration { 
public:
void method() {
   T::A *aObj; // oops ...
};
模板
课堂示范{
公众:
void方法(){
T::A*aObj;//噢。。。
};

作为上述所有帖子的补充,在处理模板参数时,必须使用
关键字(最多包括C++14),例如:

template <template <typename, typename> class Container, typename Type>
class MyContainer: public Container<Type, std::allocator<Type>>
{ /*...*/ };
这是有区别的,您应该更喜欢
class
而不是
typename
。 但是为什么呢?
typename
对于模板参数是非法的,因此为了保持一致,您应该使用
class

template<template<class> typename MyTemplate, class Bar> class Foo { };    //  :(
template<template<class>    class MyTemplate, class Bar> class Foo { };    //  :)
模板类Foo{};/:(
模板类Foo{};/:)

当然,typename也是重载的……没错,但它似乎没有那么令人困惑的重载——
typename
的其他用法之所以让人困惑,并不是因为重载,而是因为需要重载的情况非常混乱。其他关键字重载(
class
static
)我不得不同意在这里使用
typename
——类的使用似乎过度使用了这个关键词,特别是在
模板类Y{…
的实例中,我个人觉得这很容易