【发布时间】: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 <set> 而不是#include <vector>,并将main() 更改如下:
int main()
{
std::set<CString> s;
s.insert(_T("Test"));
s.begin()->Trim();
return 0;
}
但是,这给了我在s.begin()->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