【问题标题】:Difference between std::greater<int>() and std::greater<int>?std::greater<int>() 和 std::greater<int> 之间的区别?
【发布时间】:2017-05-29 11:05:59
【问题描述】:

此代码有效:

#include <iostream>
#include <queue>
#include <vector>
#include <functional>
using namespace std;
int main(){
    priority_queue<int,vector<int>,greater<int> > pq;
    pq.push(1);
    cout<<pq.top()<<endl;
}

但是,这段代码无法编译:

#include <iostream>
#include <queue>
#include <vector>
#include <functional>
using namespace std;
int main(){
    priority_queue<int,vector<int>,greater<int>() > pq;
    pq.push(1);
    cout<<pq.top()<<endl;
}

为什么?
我所了解的是greater&lt;int&gt;() 是一个函数对象,priority_queue 接受一个二元谓词作为第三个参数,谓词是一种特殊类型的函子。 但是这对大括号是如何产生这种差异的。

【问题讨论】:

  • 那么,函数和调用函数有什么不同呢?
  • std::greater&lt;int&gt; 是一个类型,用 () 就变成了构造函数调用
  • 因为第三个模板参数应该是 type 而不是对象?
  • 我真的不明白这个问题。为什么对 C++ 代码添加随机括号会导致编译错误感到惊讶?
  • @Manohar 我想知道你的问题被否决了。事实上,这里的大多数 cmets 都是错误的。这表明你的问题很好。我投了赞成票。

标签: c++ c++11 templates predicate functor


【解决方案1】:

在此声明中

priority_queue<int,vector<int>,greater<int> > pq;

类型模板参数greater&lt;int&gt;对应结构的类型。

在此声明中

priority_queue<int,vector<int>,greater<int>() > pq;

类型模板参数greater&lt;int&gt;()对应一个没有参数且返回类型为greater&lt;int&gt;的函数的类型

类模板std::priority_queue 期望参数是作为函数指针的函数对象类型或具有函数运算符的类类型。

为了更清楚地比较例如这些声明

std::vector<int()> v1;

std::vector<int (*)()> v2;

对于第一个声明,编译器将发出错误,因为运算符 sizeof 可能不适用于函数类型 int(),并且向量将无法为其元素分配内存。这里用作类型模板参数的int() 不是表达式。它是一个类型 ID。

在第二个声明中,向量处理指向函数的指针,它可以为其指针元素分配内存。

【讨论】:

  • 谢谢先生。这就是我所要求的。
  • @Manohar 完全没有:)
  • "类型模板参数greater()对应的函数的类型没有参数,返回类型更大" greater&lt;int&gt;()不是临时函数对象?
  • @Iamanon 是一个类型模板参数,表示函数类型。
【解决方案2】:

来自cppreference

template<
     class T,
     class Container = std::vector<T>,
     class Compare = std::less<typename Container::value_type>
 > class priority_queue;

Compare - 比较 type 提供严格的弱排序。

因此,对于 std::priority_queue,您将比较器类型作为模板参数传递。

另一方面,

greater<int>()

代表创建greater&lt;int&gt; 类型的新对象,这在您的情况下不是一个选项。

【讨论】:

  • 您的回答很有意义。您能否提供一些关于“类型”如何比较事物的见解。到目前为止,我只使用并看到了用于 comapring 的函数、函子和 lamdas。
  • @Manohar 我猜 priority_queue 只是创建了一个 Comparator 的实例来比较事物。
  • 函数、函子和lambas都有一个类型。由于类/函数应该接受其中的任何一个,因此必须对其进行模板化。大多数时候(算法库等)这种类型是推断出来的,你不需要明确地提供它stackoverflow.com/questions/356950/c-functors-and-their-uses
猜你喜欢
  • 2021-10-29
  • 1970-01-01
  • 2010-11-18
  • 2019-02-11
  • 2014-10-29
  • 2013-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多