【问题标题】:How can I trim strings stored in a std::set?如何修剪存储在 std::set 中的字符串?
【发布时间】:2017-07-20 15:00:11
【问题描述】:

我正在使用 VS 2012 开发 MFC 应用程序。在此应用程序中,我想使用 Trim() 成员函数清理 CString 对象的容器。首先,我使用了一个std::vector作为容器,如下图MCVE

#define _AFXDLL    // CString
#include <afx.h>   // CString
#include <vector>

int main()
{
    std::vector<CString> v;
    v.push_back(_T("Test"));
    v.begin()->Trim();
    return 0;
}

这会按预期编译和工作。然后,我想用std::set 替换std::vector。因此,我包含#include &lt;set&gt; 而不是#include &lt;vector&gt;,并将main() 更改如下:

int main()
{
    std::set<CString> s;
    s.insert(_T("Test"));
    s.begin()->Trim();
    return 0;
}

但是,这给了我在s.begin()-&gt;Trim(); 行上的以下编译错误:

错误 C2663: 'ATL::CStringT>>::Trim' : 3 个重载对 'this' 指针没有合法转换

documentation of the error 基本上说:

[...] 此错误可能是由于在 const 对象上调用非 const 成员函数引起的。 [...]

但是,与vector 版本相比,我没有添加任何const 限定符。此外,std::set::begin() 提供了一个非const 迭代器,就像std::vector::begin() 一样。我在错误 C2663 上发现了类似的问题,例如,this 一。但在大多数情况下,有人试图从 const 函数中修改成员,而我的代码中并非如此。

为什么我不能在std::set 中的CString 对象上使用Trim(),我该如何解决这个问题?

【问题讨论】:

  • std::set 中的值是const,因为它们也是定义集合中顺序的键。
  • 他们需要,std::set(和std::map)在内部将其数据组织在二叉搜索树中,通常是红/黑树。如果您修改了条目(仅用于地图的键),您将破坏排序顺序和任何保证......
  • set 中的元素是 const,因为更改它们可能会更改它们的相对顺序,从而破坏设置的内部数据结构(通常是某种平衡树),因为它可能会改变各种元素之间的排序关系 - 这绝对是您想做的事情。
  • 谢谢大家!阅读您的 cmets 后,这一点非常明显。我真的应该能够自己解决这个问题。我想我老了……

标签: c++ string windows mfc set


【解决方案1】:

如何修剪存储在 std::set 中的字符串?

你不能也不应该。 std::set 中的元素是内部排序的。如果允许您在原地更改它们,那将破坏排序。

您最好的选择是从集合中删除现有项目并将修改后的项目添加到集合中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-06-29
    • 2022-01-01
    • 1970-01-01
    • 2022-06-22
    • 2015-08-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多