来自“const int*”的转换无效;到“int*”在获取 std::set 元素地址时
我收到以下错误 error: invalid conversion from 'const int*' to 'int*'
以下是我的程序,
#include <set>
int main ( int argc, char **argv) {
std::set<int> intSet;
intSet.insert(1);
intSet.insert(2);
intSet.insert(3);
intSet.insert(4);
intSet.insert(5);
int *pAddress = &(*(intSet.find(4)));
}
我想要 std::set
中元素的地址,此代码不会在 Microsoft 编译器中给出任何编译错误,但 g++
会给出此编译错误。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这是因为
std::set
的每个元素都存储为T const
,并且实现有这样做的理由。由于
std::set
恰好包含值的单个副本。它必须使其不可变,否则,可以将其值更改为集合中已存在的值。即使元素是可变的,您也无法更改值,因为 std::set::find 是 const 成员函数,因此在此函数中
intSet
是不可变,并且实际上每个元素也将变得不可变,包括迭代器 > 它返回它,并且通过它你可能更改调用站点的值。唯一想要获取的地址是这样的:
不过不要使用
const_cast
,It is because each element of
std::set
is stored asT const
, and the implementation has a reason to do so.Since
std::set
contains exactly a single copy of a value. It has to make it immutable, otherwise, one can change it's value to something which already exists in the set.Even if the elements were mutable, you would not be able the change the value, because
std::set::find
is aconst
member function, and therefore in this functionintSet
is immutable and effectively each elements would become immutable as well, including the iterator which it returns, and through which you may change the value at the call-site.The only want to take the address is this:
Don't use
const_cast
though,GCC 定义
set::iterator
为set::const_iterator
,防止您将非const
引用或指针绑定到set::find()
的结果。 C++11 允许此行为(它规定键是不可变的,并且set::iterator
是常量迭代器),但在 C++03 中是不正确的。在 C++03 中,不应修改集合的元素,因为这可能会破坏集合中元素的顺序。在某些情况下,您可能想要 - 如果类型是类,并且仅使用某些成员来定义顺序,则修改其他成员是有效的。 C++03 标准允许这样做,但您必须小心不要修改顺序,因为这会产生未定义的行为。在 C++11 中,这是不允许的,并且实现可能会阻止这种情况。
在您的情况下,您根本无法合法地修改该值,因此您可以修复 C++11 的代码,并通过绑定到 const 指针来提高其安全性。
GCC defines
set::iterator
to beset::const_iterator
, preventing you from binding a non-const
reference or pointer to the result ofset::find()
. This behaviour is allowed by C++11 (which states that keys are immutable, and thatset::iterator
is a constant iterator), but was incorrect in C++03.In C++03, you shouldn't modify the elements of a set since that can break the ordering of elements within it. In some cases, you might want to - if the type is a class, and only some members are used to define the ordering, then it was valid to modify other members. The C++03 standard allows this, but you must be careful not to modify the order as that will give undefined behaviour. In C++11, this isn't allowed, and the implementation may prevent this.
In your case, you can't legally modify the value at all, so you can fix your code for C++11, and also improve its safety, by binding to a pointer-to-const.
集合的值是不可变的,以便类可以保证所有元素都是唯一的。给你一个非 const 指针会让你很容易改变值,这会破坏集合模板类的设计 (http://msdn.microsoft.com/en-us/library/e8wh7665(VS.80).aspx)。
您应该更改最后一行,使其前面有一个“const”,如下所示:
仅供参考:您的代码在 Visual Studio 2010 中给出了相同的编译错误。
The values of the set are meant to be immutable so that the class can guarantee that all of the elements are unique. Giving you a non-
const
pointer would make it too easy for you to change the value, which would break the design of the set template class (http://msdn.microsoft.com/en-us/library/e8wh7665(VS.80).aspx).You should change the last line to have a "const" in front of it like so:
FYI: Your code gives an identical compilation error in Visual Studio 2010.