作者poyenc (发箍)
看板C_and_CPP
标题Re: [问题] C++ 如何修改compare
时间Fri Apr 19 22:03:02 2019
※ 引述《a29831968 (yeah is you)》之铭言:
: 开发平台(Platform): (Ex: Win10, Linux, ...)
: 编译器(Ex: GCC, clang, VC++...)+目标环境(跟开发平台不同的话需列出)
: 额外使用到的函数库(Library Used): (Ex: OpenGL, ...)
: 问题(Question):
: 喂入的资料(Input):
: 预期的正确结果(Expected Output):
: 错误结果(Wrong Output):
: 程式码(Code):(请善用置底文网页, 记得排版,禁止使用图档)
: 不好意思,我是在刷题的时候遇到问题
: 可能关键字下错所以一直找不太到答案,所以想在这里求助大神
: 一般来说
: 定义 priority_queue<>时,第三个参数放的是compare
: 在刷题时,模板是这样子
: class solution{
: // 里面会有题目自订的funciton
: // 若是我在题目内宣告priority_queue,且要用到符合需求的compare时,
: // 我会在该class外面自行定义
: vector<int> mergeTwoSortedArray(vector<int> a, vector<int> b) {
: // 随便假设
: priority_queue<int, vector<int>, compare> pq;
: }
: };
: // ex
: class compare{
: bool operator()(const int &a, const int &b) {
: return a > b;
: }
: };
: 可是我现在需要在class solution题目给的function内去更改compare,
: 因为我需要使用到题目给的input,不单单只是整数,说不定要用到a的size之类的(假设)
: 补充说明(Supplement):
: 抱歉,第一次发文,若有什麽不妥或不符合规定请告知,会改进
: 谢谢各位的帮忙。
除了语法问题, 小弟来补充一下你可能不知道的二三事, 通常
STL algorithms/containers 使用你给的 function objects 时都
会有以下常见的需求:
1. consistent behavior
2. copy constructible
3. stateless
4. callable by given arguments
第一点很合理, 假如我现在写了自己的 less 比较两个整数, 前 10
次呼叫 less{}(1, 2) 会回传 true, 但第 11 次开始回传 false,
想当然拿来当排序准则是会失败的:
https://bit.ly/2VbG9m2
第二点在该 algorithm/container 使用期间, 你给的 function
object 必须一直存活着, 所以通常介面会用 const T& 来接你给的
物件引数, 而它们会
复制一份在内部使用, 这个通常在规格书或
cppreference 找得到:
http://eel.is/c++draft/priority.queue#priqueue.cons
第三点比较像是前两点的综合, 因为会复制资料成员(复制状态),
在 algorithms/containers 内部使用时可能行为就变掉不如预期
第四点要先
知道给的物件会被怎样使用, 不然会得到一大坨编译错
误不知道该怎麽办, 也是文件就找得到:
https://bit.ly/2GmpPpf
因为 std::priority_queue 类别模版接的都是型别引数, 所以你
需要
在编译的时候想办法推导出来. 就我所知有两种方法给你参考:
其中一种是自订型别, 提供多载 operator(); 另一种是先用
lambda expression 建立 closure, 再
透过 decltype() 得到它的
型别, 当作引数传给 std::priority_queue 类别模版
方法一 https://bit.ly/2vcOIOV
方法二 https://bit.ly/2L4ucen
happy coding!
--
P1389R0: Guidelines for Teaching C++ to Beginners
https://bit.ly/2GvDWKb
SG20 Education and Recommended Videos for Teaching C++
https://www.cjdb.com.au/sg20-and-videos
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 150.116.41.131
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/C_and_CPP/M.1555682594.A.F94.html
1F:推 heardringo: 推 04/19 23:26
2F:推 TitanEric: 优文 04/20 00:12
3F:推 ggBird: 好 04/20 06:45
4F:推 bigbite: 优文 04/20 10:17
5F:推 aa0917954358: 可以请教一下 overloading operator()跟operator< 04/20 22:36
6F:→ aa0917954358: 当作compare function的概念差在哪里吗? 04/20 22:36
好问题! 除非你是直接指定函式的位址, 不然差别在於
决定呼叫对
象的时机. 假设我有一个 template function, 做的事只有印出两
个参数用 operator<() 比较的结果:
template <
typename T>
void test(
const T& lhs,
const T& rhs) {
std::cout << std::boolalpha << (lhs < rhs) << std::endl;
}
在模版被具现化 (instantiate) 以前, 还不会决定叫用的函式, 但
是当
触发具现化或做全特化 (full specialization) 时, 就需要找
个可用 operator<() 函式实体来呼叫, 这时候就看当下情境有哪些
选项让编译器挑. 你可以参考下面的范例:
https://bit.ly/2Gpc6hp
这个在分离编译的时候, 常因为编译器看到的运算子对象不同造成
混淆, 所以通常类别的实作者都会提供预设的 operator<() 实作放
在同一个命名空间下, 并且
藉助 ADL (Argument Dependent Lookup
) 让编译器能找到同一个对象. 只不过这个预设的运算子合不合用
就要看个别使用情境了
另一方面如果直接指定一个 function object 就不需要後续查找函
式的流程 (如果没有像 std::less 间接查找的话)
※ 编辑: poyenc (150.116.41.131), 04/21/2019 08:14:26
7F:推 aa0917954358: 谢谢回答! 04/21 21:17