为什么 set::find 不是模板?

2024-03-24

模板函数来自<algorithm>你可以做这样的事情

struct foo
{
    int bar, baz;
};

struct bar_less
{
    // compare foo with foo
    bool operator()(const foo& lh, const foo& rh) const
    {
        return lh.bar < rh.bar;
    }
    template<typename T>  // compare some T with foo
    bool operator()(T lh, const foo& rh) const
    {
        return lh < rh.bar;
    }
    template<typename T>  // compare foo with some T
    bool operator()(const foo& lh, T rh) const
    {
        return lh.bar < rh;
    }
};

int main()
{
    foo foos[] = { {1, 2}, {2, 3}, {4, 5} };
    bar_less cmp;
    int bar_value = 2;
    // find element {2, 3} using an int
    auto it = std::lower_bound(begin(foos), end(foos), bar_value, cmp);
    std::cout << it->baz;
}

In std::set方法如find你必须传递一个类型的对象set::key_type这通常会迫使您创建一个虚拟对象。

set<foo> foos;
foo search_dummy = {2,3};  // don't need a full foo object;
auto it = foos.find(search_dummy);

如果有人可以打电话的话,那就太有帮助了foos.find(2)。有什么理由吗find不能是模板,接受可以传递给 less 谓词的所有内容。如果它只是丢失了,为什么 C++11 中没有它(我认为不是)。

Edit

主要问题是为什么它不可能,如果它是可能的,为什么决定标准不提供它。第二个问题您可以提出解决方法:-) (boost::multi_index_container我刚才想到的是,它提供了从值类型中提取键的功能)

构造值类型更昂贵的另一个示例。钥匙name是类型的一部分,不应用作映射键中的副本;

struct Person
{
    std::string name;
    std::string adress;
    std::string phone, email, fax, stackoferflowNickname;
    int age;
    std::vector<Person*> friends;
    std::vector<Relation> relations;
};

struct PersonOrder
{
    // assume that the full name is an unique identifier
    bool operator()(const Person& lh, const Person& rh) const
    {
        return lh.name < rh.name;
    }
};

class PersonRepository
{
public:

    const Person& FindPerson(const std::string& name) const
    {
        Person searchDummy;  // ouch
        searchDummy.name = name;
        return FindPerson(searchDummy);
    }

    const Person& FindPerson(const Person& person) const;

private:
    std::set<Person, PersonOrder> persons_;
    // what i want to avoid
    // std::map<std::string, Person> persons_;
    // Person searchDummyForReuseButNotThreadSafe;

};

std::find_if适用于未排序的范围。所以你可以传递任何你想要的谓词。

std::set<T>总是使用Comparator模板参数(std::less<T>默认情况下)来维护集合的顺序,以及再次查找元素。

So if std::set::find是模板化的,它必须要求您只传递一个观察比较器总排序的谓词。

话又说回来,std::lower_bound所有其他适用于排序范围的算法都已经要求这一点,因此这不会是一个新的或令人惊讶的要求。

所以,我想这只是一个疏忽,没有find_if()(说)在std::set。建议将其用于 C++17 :) (EDIT:: EASTL 已经有这个了 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2271.html,他们使用了一个比我更好的名字:find_as).

也就是说,你知道你不应该使用std::set http://lafstern.org/matt/col1.pdf, 你?在大多数情况下,排序向量会更快,并为您提供了所缺乏的灵活性std::set.

EDIT:正如 Nicol 指出的,这个概念有一些实现Boost http://www.boost.org/doc/libs/1_49_0/doc/html/container/non_standard_containers.html#container.non_standard_containers.flat_xxx and Loki http://loki-lib.sourceforge.net/html/a00025.html(以及其他地方,我确信),但是鉴于您无法利用它们的主要优势(内置find()方法),使用裸露不会损失太多std::vector.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 set::find 不是模板? 的相关文章

随机推荐

  • jTable 中的 jButton 不可点击

    我遇到了问题 我无法单击按钮 它们的行为就像只是带有按钮设计的文本字段 my Main tableModStudents DefaultTableModel studentsTable getModel studentsTable getC
  • C# - 哪个更快:String.Contains() 或 Regex.isMatch()? [复制]

    这个问题在这里已经有答案了 可能的重复 Regex IsMatch 与 string Contains https stackoverflow com questions 2962670 regex ismatch vs string co
  • 为什么 System.out.print 会导致自动刷新?

    System out 是一个 PrintStream 对象 我阅读了有关 PrintStream 的文档 我不明白的是为什么 System out print 会导致缓冲区被刷新 这种情况不应该只发生在 println 中吗 这种情况不应该
  • IndexError:读取 python 的 CSV 文件中的列表索引超出范围

    我有一个包含 30000000 个条目的 csv 文件 像这样 3 2 2 2 2 2 2 当我尝试颠倒词序时 我收到以下错误 Traceback most recent call last File home grpus dg py li
  • 如何在 CodeIgniter 中创建库类的多个实例?

    我想在 CodeIgniter 中创建一个类的多个实例 我已将我的类创建为一个库 但无法弄清楚用于创建多个实例的语法 来自 CodeIgniter 用户指南 CI 用户指南 加载器类 http codeigniter com user gu
  • 将 puppeteer 与 imgui-js 结合使用

    如果问题的长度可能很吓人 问题的摘要是如何从节点服务器与前端应用程序交互 我相信 Puppeteer 的使用应该伴随着该请求的解决 问题很大 因为我解释了我在浏览器中实现后端代码 傀儡师 工作的所有失败尝试 除了构建和运行存储库之外 尽管按
  • Android Fragment 中的 EditText 值不刷新

    我正在使用Viewpager在 3 之间切换fragments 一切工作正常 除了第二个选项卡的刷新 或fragment 在这个选项卡中 我有一张图片 一些静态的Textviews 一些动态TextViews还有一些EditText fie
  • 如何生成 pool_transactions_genesis 和domain_transactions_genesis?

    我正在尝试创建 Hyperledger Indy 网络 并且一直在遵循阅读文档 https hyperledger indy readthedocs io projects node en latest start nodes html 我
  • 在 SQL 中的 CAST 中使用 & 符号

    SQL Server 2005 上的以下代码片段在与号 上失败 select cast
  • 在两个片段之间拖放

    我正在研究用户界面上同时可见的两个不同片段之间的拖放操作 我想将视图从一个片段拖到另一个片段中 我可以在片段之间拖动它 但我面临的不好的是我无法在第二个片段上监听 onDrag 以获取第一个片段的视图 简而言之 第二个片段上的 OnDrag
  • 如何将 Play 与自定义模块和持续集成结合使用

    如何在 CI 系统中设置 Play 应用程序和 自定义 Play 模块的构建 以便当模块的构建良好时 构建会将模块工件安装在本地存储库中和 或将它们部署到远程存储库 并且应用程序使用该存储库中的工件 该解决方案也应该适合在本地工作的开发人员
  • Android 应用内计费 v3:“无法执行操作:queryInventory”

    我第一次使用新的 v3 API 设置应用内结算 它在我的设备上运行正常 但我收到了其他用户的很多错误报告 其中之一是 java lang IllegalStateException IAB helper is not set up Can
  • 如何定义,系统中DEP为ON

    德尔福Xe XP Vista Win7 WAR 2008R2 0 支持DEP 数据执行保护 CPU Function isCpuDEP bool begin Result end 1 如何定义系统中DEP为ON Function isEna
  • 无法获取用户列表[重复]

    这个问题在这里已经有答案了 我想在我的应用程序中显示用户列表 我使用默认的Auth来自 firebase 的系统 但回复总是空的 FIRDatabase database reference child users queryOrdered
  • 如何检查 JavaScript 对象是否是 DOM 对象?

    我试图得到 document createElement div gt true tagName foobar something gt false 在我自己的脚本中 我曾经只使用它 因为我从来不需要tagName作为财产 if objec
  • 拖动 D3 节点时防止单击操作

    我可以单击 D3 节点来获取alert 信息 我也可以拖动 D3 节点 但拖动也会在释放鼠标时触发单击行为 有没有办法阻止拖动节点后的点击行为 这就是我所说的拖动 var node svg selectAll node data graph
  • 使用 clickonce 在 C# 解决方案中部署外部文件

    我在使用 Visual Studio Express 2010 c 版本时遇到问题 我有一个引用 DLL 的项目 该 DLL 有一个外部 Excel 文件标记为 构建行动 内容 复制到输出目录 始终复制 当我构建解决方案时 此 Excel
  • 矢量形式的垂直风可视化

    我有屏蔽数组格式的垂直风数据 我想将其绘制成矢量形式 masked array data 4 06932000e 04 4 06932000e 04 5 70601827e 04 2 43262173e 04 2 43262173e 04
  • Visual SVN Server:提交前/提交后挂钩指南

    考虑到这里的评论 这可能是最好的维基百科 分享常用 有用的 SVN 预提交钩子 https stackoverflow com questions 884608 share common useful svn pre commit hook
  • 为什么 set::find 不是模板?

    模板函数来自