容器和类型的模板函数,用于比较指针向量

时间:2018-11-07 18:59:54

标签: c++ templates

我想比较2个指针容器(向量或集合)。我正在尝试拥有一个与类型无关的函数。

首先,我尝试了以下方法。但是问题在于,即使两个容器都具有相同内容的对象,它始终返回0。

  template<typename Container >
    bool isEqual(const Container &lhs,const Container &rhs ) {
        bool ok = equal(begin(lhs), end(lhs), begin(rhs));

        return ok;
    }

然后我尝试使用以下功能:

 template<typename T , typename Container >
    bool isEqual(const Container &lhs,const Container &rhs ) {
        bool ok = equal(begin(lhs), end(lhs), begin(rhs),
                    [](const T* lhs, const T* rhs){ return *lhs == * rhs; });

        return ok;
    }

但是问题是它正在产生以下错误,我不明白为什么。

 In function 'int main()':
31:31: error: no matching function for call to 'isEqual(std::vector<Point*>&, std::vector<Point*>&)'
31:31: note: candidate is:
19:6: note: template<class T, class Container> bool isEqual(const Container&, const Container&)
19:6: note:   template argument deduction/substitution failed:
31:31: note:   couldn't deduce template parameter 'T'
36:31: error: no matching function for call to 'isEqual(std::set<Point*>&, std::set<Point*>&)'
36:31: note: candidate is:
19:6: note: template<class T, class Container> bool isEqual(const Container&, const Container&)
19:6: note:   template argument deduction/substitution failed:
36:31: note:   couldn't deduce template parameter 'T'

#include <iostream>
#include <vector>
#include <algorithm>
#include <set>

using namespace std;

class Point {
    public:
    Point(int x, int y):_x(x),_y(y) {}
    private:
     int _x;
     int _y;
};

template<typename T , typename Container >
bool isEqual(const Container &lhs,const Container &rhs ) {
    bool ok = equal(begin(lhs), end(lhs), begin(rhs),
                [](const T* lhs, const T* rhs){ return *lhs == * rhs; });

    return ok;
}

int main()
{
    std::vector<Point *> v1 = {new Point(10,10)};
    std::vector<Point *> v2  = {new Point(10,10)};

    std::cout << isEqual(v1,v2) << std::endl;

    std::set<Point *> s1 = {new Point(10,10)};
    std::set<Point *> s2  = {new Point(10,10)};

    std::cout << isEqual(s1,s2) << std::endl;

    return 0;
} 

2 个答案:

答案 0 :(得分:1)

问题

template<typename T , typename Container >
bool isEqual(const Container &lhs,const Container &rhs ) {
    bool ok = equal(begin(lhs), end(lhs), begin(rhs),
                [](const T* lhs, const T* rhs){ return *lhs == * rhs; });

    return ok;
}

是无法推断出T是什么。由于在函数参数中未使用它,因此编译器不知道它应该是什么,因此在调用函数时必须告诉它。也就是说,您实际上不需要T。我们可以使用auto参数重写lambda,这会将lambda的函数调用运算符转换为模板。这会将代码更改为

template<typename Container >
bool isEqual(const Container &lhs,const Container &rhs ) {
    bool ok = equal(begin(lhs), end(lhs), begin(rhs),
                [](const auto* lhs, const auto* rhs){ return *lhs == * rhs; });

    return ok;
}

带您去下一期。 *lhs == * rhs使用operator ==比较对象。您尚未为operator ==定义Point,所以它不会编译。您需要将Point更改为

class Point {
    public:
    Point(int x, int y):_x(x),_y(y) {}
    bool operator ==(const Point& rhs) { return std::tie(_x, _y) == std::tie(rhs._x, rhs._y); }
    private:
     int _x;
     int _y;
};

因此它们实际上可以进行比较。


请注意,如果您使用std::vector<Point>而不是std::vector<Point *>,那么std::vector提供了它自己的operator ==,您可以通过比较两个std::vector<Point>

std::vector<Point> v1;
// fill v1
std::vector<Point> v2
// fill v2
if (v1 == v2)
    // vectors are equal.

您似乎没有任何理由拥有std::vector<Point *>,因此我建议使用此解决方案。

答案 1 :(得分:0)

因为您已经问过“我想比较2个指针容器(向量或集合)”。 我建议您使用以下std::equal形式进行元素之间的比较,因为您提到的形式仅将其比较直到第一个容器的长度。

template<typename Container >
bool isEqual(const Container &lhs,const Container &rhs ) {
bool ok = equal(begin(lhs), end(lhs), begin(rhs), end(rhs),
    [](const auto* lhs, const auto* rhs){ return *lhs == * rhs; });

return ok;
}

话虽如此,您仍然必须为最终执行的比较定义 == 运算符。就像上面的答案一样。