可以使用 std::unique 来确定自定义类的对象是不是具有相同的值吗?

Posted

技术标签:

【中文标题】可以使用 std::unique 来确定自定义类的对象是不是具有相同的值吗?【英文标题】:can std::unique be used to determine if objects of a custom class have the same values?可以使用 std::unique 来确定自定义类的对象是否具有相同的值吗? 【发布时间】:2017-12-04 17:06:15 【问题描述】:

我有一个帧速率列表和一个相关屏幕分辨率的列表。问题是我的解决方案列表中有大量重复项。实际上,我在帧速率列表中也有大量重复项(非常感谢,Windows!),但是当我对原始列表进行排序时,通过简单的比较就可以消除这些重复项。我想我想使用std::algorithm 来帮助我消除重复项,但我无法让它工作。

代码:

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

struct resolution 
    int w;
    int h;
;

int main(void) 

    std::vector<std::pair<int, std::vector<resolution>>> vec;
    for (int i = 0; i < 5; i++) 
        std::pair<int, std::vector<resolution>> p;
        p.first = i;
        for (int j = 0; j < 5; j++) 
            resolution res;
            res.w = j;
            res.h = j;
            p.second.push_back(res);
        
        vec.push_back(p);
    

    for (std::vector<std::pair<int, std::vector<resolution>>>::iterator it = vec.begin();
        it != vec.end();
        ++it) 
        it->second.erase(std::unique(it->second.begin(), it->second.end()), it->second.end());
    

    for (std::vector<std::pair<int, std::vector<resolution>>>::iterator it1 = vec.begin();
        it1 != vec.end();
        ++it1) 
        for (std::vector<resolution>::iterator it2 = it1->second.begin();
            it2 != it1->second.end();
            ++it2) 
            std::cout << it1->first << ": " << it2->w << " x " << it2->h << std::endl;
        
    

    return 0;

我从算法中得到以下编译器错误:

Error   C2672   'operator __surrogate_func': no matching overloaded function found  dummy_erase c:\program files (x86)\microsoft visual studio 14.0\vc\include\algorithm    1503    
Error   C2893   Failed to specialize function template 'unknown-type std::equal_to<void>::operator ()(_Ty1 &&,_Ty2 &&) const'   dummy_erase c:\program files (x86)\microsoft visual studio 14.0\vc\include\algorithm    1503    
Error   C2672   'operator __surrogate_func': no matching overloaded function found  dummy_erase c:\program files (x86)\microsoft visual studio 14.0\vc\include\algorithm    1506    
Error   C2893   Failed to specialize function template 'unknown-type std::equal_to<void>::operator ()(_Ty1 &&,_Ty2 &&) const'   dummy_erase c:\program files (x86)\microsoft visual studio 14.0\vc\include\algorithm    1506    

我对@9​​87654324@ 没有太多经验,但我怀疑问题是std::unique 不明白如何比较我的resolution 对象。如果确实如此,我是否可以在我的resolution 类中添加一些内容以使其对std::unique 更好?或者,有没有其他方法可以优雅地做到这一点?

我总是可以通过在列表上的另一次传递和一些条件来手动完成,但避免做那种事情正是使用 C++ 而不是 C 的原因之一。如果有一个技巧,我'很想知道。

【问题讨论】:

为什么不std::set&lt;resolution&gt; [OT]: std::vector&lt;std::pair&lt;int, std::vector&lt;resolution&gt;&gt;&gt;::iterator it = vec.begin() 现在可以写成auto it = vec.begin()。和for (std::vector&lt;std::pair&lt;int, std::vector&lt;resolution&gt;&gt;&gt;::iterator it = vec.begin(); it != vec.end(); ++it) auto&amp; p = *it; /*...*/ 替换为for (auto&amp; p : vec) /*...*/ 【参考方案1】:

你必须添加一个比较器。

尝试添加

bool operator == (resolution const & r1, resolution const & r2)
  return (r1.w == r2.w) && (r1.h == r2.h); 

你可以将它写在 resolution 主体中作为 friend 函数

struct resolution 
    int w;
    int h;

    friend bool operator == (resolution const & r1, resolution const & r2)
      return (r1.w == r2.w) && (r1.h == r2.h); 
;

【讨论】:

完美。我想到可能在构造函数或其他东西中进行比较,但我不知道如何使它具有独特性。毫无疑问,它在我懒得阅读的文档中这么说......

以上是关于可以使用 std::unique 来确定自定义类的对象是不是具有相同的值吗?的主要内容,如果未能解决你的问题,请参考以下文章

一些 std::unique_ptr 使用和“陷阱”

C++ 使用带有基类的已删除函数 std::unique_ptr

std::unique_ptr 不是零成本

使用std::lock 和 std::unique_lock来起先swap操作

关于使用 std::unique_lock 的说明

模板类的树,其中 chilldren 是 std::array of std::unique_ptr