Home  >  Q&A  >  body text

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

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

#include <iostream>
#include <vector>
#include <string>

//#define NO_OPERATOR

#ifndef NO_OPERATOR

template<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 // !1


template<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;
}
怪我咯怪我咯2765 days ago718

reply all(2)I'll reply

  • 大家讲道理

    大家讲道理2017-04-17 13:34:20

    Because you overloaded the global operator==, when you determine that s1 == s2, the compiler speculates that you may want to instantiate the template parameter as
    <std:: vector<int>, std::vector<int>>, then the compiler sees first1 == last1, then the template parameter is instantiated as
    std::vector<int>::iterator, so the type derivation is It failed, and the compiler was dumbfounded.

    The container in stl overloads operator==, so just use it directly.

    reply
    0
  • 迷茫

    迷茫2017-04-17 13:34:20

    #include <iostream>
    #include <vector>
    #include <string>
    
    //#define NO_OPERATOR
    
    #ifndef NO_OPERATOR
    
    template<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 // !1
    
    
    template<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;
    }

    reply
    0
  • Cancelreply