我是C ++的新手,在我学习语言的过程中,我编写了一个模板,工作正常,但很困惑,整个过程是如何运作的!
我的模板包含一个具有operator()成员函数的结构,该函数用作std :: sort函数的谓词。模板有一个参数,它是指向类成员的指针,这样就可以传递不同的类成员作为模板的参数。
代码:
// template definition
template<typename T, string T::*mp>
struct LessThan{
inline bool operator()(const T& c1, const T& c2){
return (c1.*mp < c2.*mp);
}
};
// class definition
class Person{
public:
...
// fields I'll for sorting
string first_name;
string last_name;
};
// Somewhere in my code, create persons and fill the vector of persons
vector<Person>persons;
p1 = Person('John','Gath');
persons.push_back(p1);
...
persons.push_back(p20);
//now I want to sort my vector of persons by either frist_name or last_name
// initialize the template
LessThan<Person, &Person::first_name>lt_fname;
// my puzzle !!
std::sort(persons.begin(), persons.end(), lt_fname); //<--NOTICE, NO () when passing lt_fname
LessThan<Person, &Person::last_name>lt_lname;
std::sort(persons.begin(), persons.end(), lt_lname); // no () for lt_lname
代码编译好并运行!
让我感到困惑的是,我以前的谓词 LessThan 的版本没有使用模板,但是当它传递给sort时,不得不使用()括号!
编译器如何知道如何调用operator()函数?
保
答案 0 :(得分:3)
这一行:
// initialize the template
LessThan<Person, &Person::first_name> lt_fname;
不初始化模板,但会创建一个实例:lt_fname
。此实例传递给std::sort
。你也可以这样做:
std::sort(persons.begin(), persons.end(), LessThan<Person, &Person::first_name>());
这次你动态地实例化模板,将临时函数传递给sort函数。
编辑:排序可能会像这样:
template< class RandomIt, class Compare >
void sort( RandomIt first, RandomIt last, Compare comp )
{
// assuming RandomIt a, b are two valid items, comp is called:
auto aIsLess = comp(a, b); // it uses the operator() of `Compare`
}
答案 1 :(得分:1)
operator()
是函数调用运算符。此功能允许您将对象视为函数。
编译器如何知道如何调用operator()函数?
编译器知道您的lt_lname
是一个对象而不是函数的名称。即使您确实有一个名为lt_name
的函数,您的lt_name
声明也会隐藏该名称。唯一的另一种选择是使用对象的函数调用操作符。
编译器不会“了解这一点”。它必须这样做才能符合这个标准。
<强>更新强>
有两个版本的std::sort
,一个带有两个参数来指定要排序的范围,另一个带有一个额外的参数来指定比较函数(或仿函数)。
sort的两个参数版本使用小于运算符来比较对象。由于operator<
可以重载,因此为类定义operator<
提供了一种对该类实例集合进行排序的方法。
三个参数版本需要调用函数(或函数对象)来代替小于。你为什么要这样做?原因很多。只是一对:也许这个类的作者没有为类定义小于运算符,并且你不能改变那个类。或者您可能希望根据上下文更改小于的含义。有时您希望按创建日期对集合进行排序,其他时间按上次更改日期排序,其他时间按名称排序。