我想在列表中插入一些元素
我真正想要做的是使用“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);
}
};
感谢您的帮助!
答案 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
来强加你自己对正确的正确性的看法。但它看起来不会很漂亮。