C++ 如何在std::set<;中找到常量int*;int*>;?
首先,我有一套C++ 如何在std::set<;中找到常量int*;int*>;?,c++,templates,pointers,find,constants,C++,Templates,Pointers,Find,Constants,首先,我有一套 std::set<int*> my_set; 但是,当我尝试编译代码时,我得到以下错误: error: invalid conversion from 'const int*' to 'std::set<int*>::key_type {aka int*}' [-fpermissive] 错误:从“const int*”到“std::set::key_type{aka int*}”[-fppermissive]的转换无效 换句话说,当我调用find时
std::set<int*> my_set;
但是,当我尝试编译代码时,我得到以下错误:
error: invalid conversion from 'const int*' to 'std::set<int*>::key_type {aka int*}' [-fpermissive]
错误:从“const int*”到“std::set::key_type{aka int*}”[-fppermissive]的转换无效
换句话说,当我调用find
时,编译器试图将const int*
强制转换为int*
无论如何,我的问题是:我如何在
my_set
中找到p
,或者至少找到p
是否存在于my_set
中,使用p
和my_set
?的现有定义,您可以在搜索集合之前使用const_cast
从参数中删除常量:
返回我的设置。查找(常量转换(p))!=我的_set.end();
没有什么特别的技术原因使库不能支持您期望的内容,但另一方面,强制显式的const\u cast
是记录涉及const
指针的操作以某种方式通过集合获得非const
访问。。。可以说是很好的文档,说明出现了一些不寻常的情况。您可以这样声明集合
std::set<const int*> my_set;
std::设置我的设置;
如果您永远不需要通过从集合中获取int
的指针来修改它。如果集合中int的生存期*和值在其他地方进行管理,并且集合只是一种检查是否已经知道特定int/对象存在的方法,则可能会出现这种情况
(*虽然您实际上可以删除const int*
)std::set::const\u迭代器将允许您修改指向int
,因此不应该存在您描述的find
重载。对我来说,这似乎是使用const\u cast
的一个有效理由。我认为您可以使用const\u cast()暂时删除“const”属性。没有理由重载查找。存储int*
,这意味着可以修改引用的对象!?那么,为什么要查找对无法修改的对象的引用呢?也许您的集合应该存储const int*
s?@StroyTeller:该函数通过my_set
具有非const
访问权限,但由于它不使用该写访问权限,因此接受int const*
是有意义的。否则,一个本身只有int const*
的函数将需要const\u cast
来调用exists\u in\u my\u set
。这可能会产生误导,因为没有充分的理由将该调用强调为潜在的const-safe,前提是存在于\u我的\u集中
。所以,在这种情况下,“良好实践”确实提供了正确的方法:它使非修改函数不需要强制转换就可以从其他函数调用。我通常不喜欢那些建议实践而不解释实践的答案。这,连同@SteveJessop在OP上写的评论都非常好。如果user1158692的方法不适用,这可能是唯一的好方法。另一方面,如何使用reinterpret\u cast(my\u set)
添加常量,而不是删除常量,将my\u set
重新解释为std::set
?我不知道该方法的行为是否定义得很好,但如果定义得很好,我想该方法也会起作用。@hellogoodbay:从技术上讲,这是未定义的行为,当const\u cast
可用时,没有理由进入该领域。实际上,我希望它在任何实际的体系结构/实现中都能正常工作。您的cast意味着为不同的set
模板参数,可能还有迭代器类型和比较运算符,额外实例化find
和end
,但它们要么是内联的,要么是非常小的。我猜这可能是未定义的,由于无法保证std::set
使用的所有对象中的成员变量与std::set中的成员变量完全相同,即使它们很可能相同。因此,将其重新解释为另一种类型可能是一个坏主意。这在我的情况下确实有效!:)我想,有时当你发现自己处于像这样一个棘手的情况下,你应该问问自己,真正的问题是你认为它在哪里。我想,“删除一个const int*
”是指从集合中删除它?
return my_set.find(const_cast<int*>(p)) != my_set.end();
std::set<const int*> my_set;