Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 与将条件作为模板参数传递给sort()相比,将条件函数指针传递给qsort()的开销更小?_C++_Sorting - Fatal编程技术网

C++ 与将条件作为模板参数传递给sort()相比,将条件函数指针传递给qsort()的开销更小?

C++ 与将条件作为模板参数传递给sort()相比,将条件函数指针传递给qsort()的开销更小?,c++,sorting,C++,Sorting,在Stroustrup的书中,当他讨论标准库的设计时,他说 例如,将比较标准构建到排序函数中是不可接受的,因为 可以根据不同的标准对数据进行排序。这就是为什么C标准库qsort()将比较函数作为参数,而不是依赖于固定的东西,例如

在Stroustrup的书中,当他讨论标准库的设计时,他说

例如,将比较标准构建到排序函数中是不可接受的,因为 可以根据不同的标准对数据进行排序。这就是为什么C标准库
qsort()
将比较函数作为参数,而不是依赖于固定的东西,例如qsort()作为进一步构建库的构建块

以上这些对我来说很有意义。但在第二段,他说

那是严重的吗?在大多数情况下,可能不是。但是,函数调用开销可能会增加 控制某些算法的执行时间,并使用户寻找替代方案。通过§13.4中描述的模板参数提供比较标准的技术解决了这一问题 问题

在§13.4中,比较标准定义为具有静态成员函数的类(进行比较)。当这些类用作模板参数时,比较仍然由它们的静态成员函数完成。在我看来,调用静态成员函数仍然会有开销


Stroustrup说这话是什么意思

是一个函数模板。编译期间,将为每个类型和比较运算符创建一个单独的
sort
实例。因为对于每个
排序
实例化,类型和比较器在编译时是已知的,这允许内联比较器函数,从而避免函数调用的开销。

通过指针调用函数有两个开销:指针解引用和函数调用开销。这是一个运行时过程


模板实例化由编译器完成。指针解引用被消除,因为显然没有指针。编译器通过内联调用优化函数调用开销。

理论上没有理由认为
sort
需要比
qsort
更快。有些编译器甚至会将传递给函数“like”的函数指针内联:我相信我见过gcc或clang这样做(而不是
qsort
),甚至在函数定义位于不同的cpp文件中时也会这样做

重要的部分是,
sort
将函数对象作为类型和实例传递。为每种类型生成不同的函数:
模板
s是函数的工厂。在调用时,很容易为每个这样的函数实例确定调用的确切函数,因此内联很简单

可以对函数指针执行同样的操作,但需要从调用
qsort
的点进行内联,仔细跟踪函数指针的不变性,并知道它是从哪个函数开始的。实际上,这比上述机制要脆弱得多


类似的问题也出现在元素跨步(在对数组进行排序时明显是静态的,在使用
qsort
时更难处理)等方面。

现代编译器确实可以内联间接调用,例如通过函数指针,甚至虚拟调用。但是要对
qsort
执行此操作,
qsort
的定义必须对编译器可见,并且通常它只是
libc中的目标代码。因此,内联间接调用是不可能的。