来自“const int*”的转换无效;到“int*”在获取 std::set 元素地址时

发布于 2024-12-10 05:09:41 字数 464 浏览 1 评论 0 原文

我收到以下错误 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++ 会给出此编译错误。

I am getting following error error: invalid conversion from ‘const int*’ to ‘int*’
Following is my program

#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)));
}

I want address of the element in the std::set , This code does not give any compilation error with Microsoft compiler but g++ is giving this compilation error.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

孤独患者 2024-12-17 05:09:41

这是因为 std::set 的每个元素都存储为 T const,并且实现有这样做的理由。

由于 std::set 恰好包含值的单个副本。它必须使其不可变,否则,可以将其值更改为集合中已存在的值。

即使元素是可变的,您也无法更改值,因为 std::set::find 是 const 成员函数,因此在此函数中 intSet不可变,并且实际上每个元素也将变得不可变,包括迭代器 > 它返回它,并且通过它你可能更改调用站点的值。

唯一想要获取的地址是这样的:

int const *paddress =  &(*(intSet.find(4))); //const int* is same as int const*

不过不要使用 const_cast

//DANGEROUS - DONT DO IT
int *paddress =  const_cast<int*>(&(*(intSet.find(4)))); //will compile, 
                                                       //but it is dangerous!

//you might accidentally write
*paddress = 10; //undefined behaviour, 
                //though the compiler will let you write this

It is because each element of std::set is stored as T 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 a const member function, and therefore in this function intSet 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:

int const *paddress =  &(*(intSet.find(4))); //const int* is same as int const*

Don't use const_cast though,

//DANGEROUS - DONT DO IT
int *paddress =  const_cast<int*>(&(*(intSet.find(4)))); //will compile, 
                                                       //but it is dangerous!

//you might accidentally write
*paddress = 10; //undefined behaviour, 
                //though the compiler will let you write this
云淡风轻 2024-12-17 05:09:41

GCC 定义 set::iteratorset::const_iterator,防止您将非 const 引用或指针绑定到 set::find() 的结果。 C++11 允许此行为(它规定键是不可变的,并且 set::iterator 是常量迭代器),但在 C++03 中是不正确的。

在 C++03 中,不应修改集合的元素,因为这可能会破坏集合中元素的顺序。在某些情况下,您可能想要 - 如果类型是类,并且仅使用某些成员来定义顺序,则修改其他成员是有效的。 C++03 标准允许这样做,但您必须小心不要修改顺序,因为这会产生未定义的行为。在 C++11 中,这是不允许的,并且实现可能会阻止这种情况。

在您的情况下,您根本无法合法地修改该值,因此您可以修复 C++11 的代码,并通过绑定到 const 指针来提高其安全性。

int const *pAddress = &(*(intSet.find(4)));

GCC defines set::iterator to be set::const_iterator, preventing you from binding a non-const reference or pointer to the result of set::find(). This behaviour is allowed by C++11 (which states that keys are immutable, and that set::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.

int const *pAddress = &(*(intSet.find(4)));
ㄖ落Θ余辉 2024-12-17 05:09:41

集合的值是不可变的,以便类可以保证所有元素都是唯一的。给你一个非 const 指针会让你很容易改变值,这会破坏集合模板类的设计 (http://msdn.microsoft.com/en-us/library/e8wh7665(VS.80).aspx)。

您应该更改最后一行,使其前面有一个“const”,如下所示:

const int *pAddress = &(*(intSet.find(4)));

仅供参考:您的代码在 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:

const int *pAddress = &(*(intSet.find(4)));

FYI: Your code gives an identical compilation error in Visual Studio 2010.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文