c++ - 同样的代码为何在重载运算符函数中报错,在普通函数中没有错?

浏览:19日期:2023-05-13

问题描述

c++新手,使用vs 2015 community。刚写了一个泛型函数用来比较两个容器内的元素是否相同,原来是在重载运算符函数operator==中写的,编译出错: std::begin 未找到匹配的重载函数,我查看了vs中std::begin的定义,其中应该有匹配的函数。于是我把代码放到普通函数中,结果就可以运行通过了,代码如下,希望有人解答 (另外,如果我将两个函数的参数都改成const Vector&,就可以通过编译正确运行):

#include <iostream>#include <vector>#include <string>//#define NO_OPERATOR#ifndef NO_OPERATORtemplate<class Vector1, class Vector2>bool operator == (Vector1& con1, Vector2& con2){ auto first1 = std::begin(con1), last1 = std::end(con1); auto first2 = std::begin(con2), last2 = std::end(con2); for (; first1 != last1 && first2 != last2; ++first1, ++first2) {if (*first1 != *first2) return false; } return (first1 == last1 && first2 == last2);}#endif // !1template<class Vector1, class Vector2>bool compare_vector(Vector1& con1, Vector2& con2){ auto first1 = std::begin(con1), last1 = std::end(con1); auto first2 = std::begin(con2), last2 = std::end(con2); for (; first1 != last1 && first2 != last2; ++first1, ++first2) {if (*first1 != *first2) return false; } return (first1 == last1 && first2 == last2);}int main(){ std::vector<int> s1(10,0), s2(10,0);#ifndef NO_OPERATOR if(s1 == s2)std::cout << 'equal1' << std::endl;#endif if (compare_vector(s1, s2))std::cout << 'equal2' << std::endl; return 0;}

问题解答

回答1:

因为你重载了全局的operator==,所以当你判断s1 == s2时,编译器推测你可能要将模板参数实例化为<std::vector<int>, std::vector<int>>,然后编译器看到了first1 == last1,这时模板参数实例化为std::vector<int>::iterator,于是类型推导就失败了,编译器也傻眼了。

stl里的容器重载了operator==,所以直接用就好了。

回答2:

#include <iostream>#include <vector>#include <string>//#define NO_OPERATOR#ifndef NO_OPERATORtemplate<class Vector1, class Vector2>bool operator == (Vector1& con1, Vector2& con2) // 正如楼上 重载的全局 == , 但这种用模板重载的做法是很危险的,不可取{ auto first1 = std::begin(con1), last1 = std::end(con1); auto first2 = std::begin(con2), last2 = std::end(con2); for (; first1 != last1 && first2 != last2; ++first1, ++first2) {if (*first1 != *first2) return false; } return (first1 == last1 && first2 == last2); // == 实例化为 operator == (vector<int>::iterator&, vector<int>::iterator&) // 然后在 == 内部,std::begin的调用产生了错误}#endif // !1template<class Vector1, class Vector2>bool compare_vector(Vector1& con1, Vector2& con2){ auto first1 = std::begin(con1), last1 = std::end(con1); auto first2 = std::begin(con2), last2 = std::end(con2); for (; first1 != last1 && first2 != last2; ++first1, ++first2) {if (*first1 != *first2) return false; } return (first1 == last1 && first2 == last2);}int main(){ std::vector<int> s1(10,0), s2(10,0);#ifndef NO_OPERATOR if(s1 == s2)// == 实例化为 operator == (vector<int>&, vector<int>&)std::cout << 'equal1' << std::endl;#endif if (compare_vector(s1, s2))std::cout << 'equal2' << std::endl; return 0;}

相关文章: