const指向const数据和c ++列表的指针

时间:2013-05-13 15:29:54

标签: c++ list pointers const

我想在列表中插入一些元素 我真正想要做的是使用“insert3”,因为它保证指针不会改变,数据不会改变。
但是“insert2”和“insert3”会出现以下错误,“insert1”不会:

class A
{
public:
    std::list<int*> l;
    void insert(int* const a)
    {
        l.push_back(a); //works
    }

    void insert2(const int* a)
    {
        l.push_back(a);
        /*
        no instance of overloaded function "std::list<_Ty, _Ax>::push_back [with _Ty=int *, _Ax=std::allocator<int *>]"
            matches the argument list
        */
    }

    void insert3(const int* const a)
    {
        l.push_back(a);
    }

};

感谢您的帮助!

3 个答案:

答案 0 :(得分:2)

简短回答

您应该使用list<int const* const>作为l的类型,然后您可以使用任何插入内容,包括insert3

答案很长

通过插入list<int*>,您尝试将int const*(指向const int的指针)转换为int*(指向int的指针)。

由于您删除保证您不会编辑指针的目标,因此这不是隐式可行的。如果你真的希望这样做,你可以使用const_cast(或c-cast),但通常会抛弃const - 这是一个非常糟糕的主意(tm)。

为什么使指针本身const不会改变事物

如果你使用版本3使用int const* const(指向const int的const指针),你得到的任何东西都不会保证变量a在{{1}时不会被改变}} 在跑。通过将指针插入列表,您实际上正在复制它。这意味着无论insert3是否为a,您的结果列表项都将是您在开头指定的类型。

通过将列表放入const,您可以确保以后不能更改任何插入的指针,并且只有在明确删除指针的list<int const* const>之后才能更改指向它的值。可以插入,因为添加const总是隐含的

答案 1 :(得分:1)

更改list以指向const

std::list<const int*> l;

由于您有一个指向const参数的指针,因此不允许通过隐式转换删除其const

答案 2 :(得分:1)

这是C ++风格的编译时const-correctness类型系统的典型高级“问题”之一。

如果要在列表中存储int *指针,则无法将const int *指针添加到该列表中(原因很明显)。这将强制所有insert方法接受int *指针,而不是const int *指针。

我理解,您真正想要表达的是insert方法本身不会更改指向数据(并且它不会)。但是,正如您所看到的,insert具有一些影响深远的副作用 - 它将指针存储在列表中。如果insert接受const int *指针,这可能会违反const-correctenss。

换句话说,仅仅考虑insert自己做了什么是不够的,考虑insert对其他代码(在这种情况下)对其他代码开放的可能性也很重要可以访问相同的列表)。在您的情况下,如果您的insert悄然接受const int *指针,那么它打开的可能性很容易让其他代码中的const-correcness违规。

当然,在这种情况下,你可以使用强有力的const_cast来强加你自己对正确的正确性的看法。但它看起来不会很漂亮。