为啥我们在给出模板类型时需要加上括号
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<int>()(10, 12)
。
大致——除了措辞不准确之外,它是第二个模板参数类型的第三个函数参数,Java 的新函数类似于 C++ 的一个,只是在 C++ 中指针是显式的,在 java 中是隐式的,并且 C++ 没有自动/隐式内存管理(垃圾收集)。
这和 Java 中的 new World()
不太一样。注意 Java 类比;它们经常导致 C++ 中的麻烦。在 C++ 中,new World()
在空闲存储中创建一个对象,并为您提供指向该对象的指针。在 C++ 中,您必须在后面删除该对象。
不是引用,而是指针... C++ 知道引用和指针,它们在很多方面都不同(从用户/编码器的角度来看;技术上——如果引用被实例化的话– 您将无法在编译后的代码中区分它们)。
这是创建临时对象的通用语法,与模板无关。喜欢std::string()
。对于局部变量也是如此,但在这种情况下,您需要删除括号 (std::greater<int> g/*() skip!*/;
),否则它将是一个函数声明。另一方面,如果您将参数传递给,您将再次需要它们,例如。 G。 std::vector<int> v(7);
。为了比较:std::vector<int>* v = new std::vector<int>()
——注意指定指针类型的星号。不过,您通常不会以这种方式创建向量。
【参考方案1】:
为什么我们需要在给出模板类型时加上括号 排序(a.begin(),a.end(),更大());
std::greater
是一个类模板。 std::greater<int>
是该类模板的一个实例,并且是一种类型(更具体地说,是一种类类型)。 std::greater<int>()
是一个临时对象(模板实例类型的实例)。括号是值初始化的语法。
不能将类型作为参数传递给函数(但是,可以将类型作为模板参数传递给函数模板)。可以将临时对象作为参数传递给函数。
因此,我们使用括号来创建一个作为参数传递的对象。
PS:我说对象是一个特定于类的术语,但我认为在结构中,它可能在 c++ 中这样称呼。
如果你所说的结构是指结构:结构是类(已使用类键 struct
声明)。
所有类型的实例都是 C++ 中的对象。
【讨论】:
为什么我们没有像 nth_element(iterator, iterator, iterator, comp); 那样传入一个对象; 在集合中我们不能传递一个函数,但我们可以在 nth_element 为什么? @ShobhitTewariWhy we are not passing in an object
我们是。 std::greater<int>()
是一个对象。 In set we cannot pass a function
如果我们使用兼容类型的函数指针作为集合比较器的模板类型参数,我们可以将函数传递给集合构造函数。以上是关于为啥我们在给出模板类型时需要加上括号的主要内容,如果未能解决你的问题,请参考以下文章