解释这个c++模板是如何工作的
Explanation how this C++ template is working?
我是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()函数?
保罗这一行:
// 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函数传递一个临时变量。
EDIT: 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`
}
说明operator()
为函数调用操作符。这个功能允许你把一个对象当作一个函数来对待。
编译器如何知道如何调用operator()函数?
编译器知道您的lt_lname
是一个对象而不是一个函数名。即使您确实有一个名为lt_name
的函数,您对lt_name
的声明也隐藏了该名称。唯一的其他选择是使用对象的函数调用操作符。
编译器不会"知道这个"。它必须这样做才能符合这个标准。
std::sort
有两个版本,一个带两个实参,指定要排序的范围,另一个带一个额外的实参,指定比较函数(或functor)。
sort的双参数版本使用小于操作符来比较对象。由于operator<
可以重载,因此为类定义operator<
提供了对该类实例集合进行排序的一种方法。
三个参数的版本接受一个要调用的函数(或函数对象)来代替小于。你为什么要这么做?原因有很多。只有几个问题:可能有问题的类的作者没有为该类定义小于操作符,并且您无法更改该类。或者你想根据上下文改变less than的意思。有时您希望按创建日期排序,有时按最后更改日期排序,有时按名称排序。
- QSqlquery prepare()和bindvalue()不工作
- 导入库可以跨dll版本工作吗
- 以螺旋方式打印矩阵的程序.(工作不好)
- 对象指针在c++中是如何工作的
- 为什么在Windows上的VS 2019和Clang 9中"size_t"在没有标题的情况下工作
- VSOMEIP-2个设备之间的通信(TCP/UDP)不工作
- 为字符串中每 N 个字符插入空格的函数没有按照我认为的方式工作?
- C++为线程工作动态地分割例程
- 为什么我的 std::ref 无法按预期工作?
- 布尔比较运算符是如何在C++中工作的
- SampleConsensusPrerejective(ext.RANSAC)是如何真正工作的
- 不确定要在我的main中放入什么才能使我的代码正常工作
- 为什么std::condition_variable notify_all的工作速度比notify_one快(对于随机请
- <<操作员在下面的行中工作
- 有人能解释一下为什么下界是这样工作的吗C++的
- ExtractIconEx:可以工作,但偶尔会崩溃
- C++中的memset函数工作不正常
- 当我在第一个循环中使用"auto"时,它工作正常,但是使用"int"它会给出错误,为什么?
- 链表c++插入,所有情况都已检查,但没有任何工作
- 当 int 方法工作正常时,void 方法有何不同,或者为什么我不能调用 void 方法?