为啥我们在给出模板类型时需要加上括号

Posted

技术标签:

【中文标题】为啥我们在给出模板类型时需要加上括号【英文标题】:Why we need to put parenthesis when giving a template type为什么我们在给出模板类型时需要加上括号 【发布时间】:2021-06-13 19:32:52 【问题描述】:

您好,我正在尝试理解这段代码:

vector<int> a = 5, 3, 6, 1, 7;
sort(a.begin(), a.end(), greater<int>());
for(int i : a) cout << i << " "; cout << endl;

为什么我需要在更大的后面加上括号。这个更大的结构是这样定义的:

/// One of the @link comparison_functors comparison functors@endlink.
  template<typename _Tp>
    struct greater : public binary_function<_Tp, _Tp, bool>
    
      _GLIBCXX14_CONSTEXPR
      bool
      operator()(const _Tp& __x, const _Tp& __y) const
       return __x > __y; 
    ;

这是在 c++ 中的stl_function.h 中定义的。现在我认为它的工作方式是为此提供一个新类型或模板。比较文件将创建一个对象,然后通过operator overloading() 执行 object_name(int_value_1, int_value_2) 并返回一个布尔值,一切都是可以理解的。但是为什么当我在模板中发送这些() 时。我认为这是实现的方式有什么缺陷吗?

PS:我说对象是一个特定于类的术语,但我认为在结构中,它可能在 c++ 中这样称呼。

【问题讨论】:

括号表示构造函数被调用,即。 e.你创建这个结构的一个实例。为了比较:如果你想在这样一个新创建的(临时)对象上调用操作符,它看起来像greater&lt;int&gt;()(10, 12) 大致——除了措辞不准确之外,它是第二个模板参数类型的第三个函数参数,Java 的新函数类似于 C++ 的一个,只是在 C++ 中指针是显式的,在 java 中是隐式的,并且 C++ 没有自动/隐式内存管理(垃圾收集)。 这和 Java 中的 new World() 不太一样。注意 Java 类比;它们经常导致 C++ 中的麻烦。在 C++ 中,new World() 在空闲存储中创建一个对象,并为您提供指向该对象的指针。在 C++ 中,您必须在后面删除该对象。 不是引用,而是指针... C++ 知道引用和指针,它们在很多方面都不同(从用户/编码器的角度来看;技术上——如果引用被实例化的话– 您将无法在编译后的代码中区分它们)。 这是创建临时对象的通用语法,与模板无关。喜欢std::string()。对于局部变量也是如此,但在这种情况下,您需要删除括号 (std::greater&lt;int&gt; g/*() skip!*/;),否则它将是一个函数声明。另一方面,如果您将参数传递给,您将再次需要它们,例如。 G。 std::vector&lt;int&gt; v(7);。为了比较:std::vector&lt;int&gt;* v = new std::vector&lt;int&gt;()——注意指定指针类型的星号。不过,您通常不会以这种方式创建向量。 【参考方案1】:

为什么我们需要在给出模板类型时加上括号 排序(a.begin(),a.end(),更大());

std::greater 是一个类模板。 std::greater&lt;int&gt; 是该类模板的一个实例,并且是一种类型(更具体地说,是一种类类型)。 std::greater&lt;int&gt;() 是一个临时对象(模板实例类型的实例)。括号是值初始化的语法。

不能将类型作为参数传递给函数(但是,可以将类型作为模板参数传递给函数模板)。可以将临时对象作为参数传递给函数。

因此,我们使用括号来创建一个作为参数传递的对象。

PS:我说对象是一个特定于类的术语,但我认为在结构中,它可能在 c++ 中这样称呼。

如果你所说的结构是指结构:结构是类(已使用类键 struct 声明)。

所有类型的实例都是 C++ 中的对象。

【讨论】:

为什么我们没有像 nth_element(iterator, iterator, iterator, comp); 那样传入一个对象; 在集合中我们不能传递一个函数,但我们可以在 nth_element 为什么? @ShobhitTewari Why we are not passing in an object 我们是。 std::greater&lt;int&gt;() 是一个对象。 In set we cannot pass a function 如果我们使用兼容类型的函数指针作为集合比较器的模板类型参数,我们可以将函数传递给集合构造函数。

以上是关于为啥我们在给出模板类型时需要加上括号的主要内容,如果未能解决你的问题,请参考以下文章

类模板,链表,直接插入排序,选择排序,起泡排序

为啥在模板中呈现时表单中的 NullBooleanField 会给出下拉列表?

类模板

为啥我需要在这里指定模板化函数的模板参数类型?

模板入门学习

函数模板与类模板