C++如何将非常量列表传递给需要常量列表的函数

发布于 2024-10-13 18:19:12 字数 173 浏览 3 评论 0原文

我有一个带签名的函数

void Foo(list<const A*>)

,我想将其传递给 a

list<A*>

我该如何做? (请注意 - 列表不是恒定的,只有列表的成员)

I have a function with a signature

void Foo(list<const A*>)

and I want to pass it a

list<A*>

How do I do this?
(plz note - the list isn't constant, only the member of the list)

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

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

发布评论

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

评论(4

孤独难免 2024-10-20 18:19:12

您遇到的问题是,即使 T * 可以隐式转换为 T const *,模板系统并不“意识到”这一点,因此 >whateverwhatever 是完全不相关的类型,并且不存在从一种类型到另一种类型的隐式转换。

为了避免这个问题,我可能会根本避免传递集合。相反,我会让该函数采用一对迭代器。 list::iterator 可以隐式转换为 list::const_iterator。就此而言,我可能会将函数设为模板,这样它就可以采用任意类型的迭代器。

这可能会为您省去很多麻烦 - list 很少是容器的不错选择,因此很有可能有一天您会想要从 list< 进行更改;A *>vector 或者 deque ——如果你让你的函数变得通用,你'无需重写该函数就可以做到这一点。

The problem you have is that even though T * can be implicitly converted to a T const *, the template system isn't "aware" of that, so a whatever<T *> and whatever<T const *> are completely unrelated types, and there's no implicit conversion from one to the other.

To avoid the problem, I'd probably avoid passing a collection at all. Instead I'd have the function take a pair of iterators. A list<A *>::iterator can be implicitly converted to a list<A *>::const_iterator. For that matter, I'd probably make the function a template, so it can take iterators of arbitrary type.

This is likely to save you quite a bit of trouble -- a list is only rarely a good choice of container, so there's a very large chance that someday you'll want to change from list<A *> to vector<A *> or perhaps deque<A *> -- and if you make your function generic, you'll be able to do that without rewriting the function at all.

夏了南城 2024-10-20 18:19:12

您只需创建一个新列表并使用原始列表中的值填充它即可。就运行时和内存管理而言,也许不是最有效的解决方案,但肯定很容易编码:

list<A*> list1;
list<const A*> list2;
for(list<A*>::iterator a=list1.begin(); a!=list1.end(); a++) list2.push_back(*a);

You can just create a new list and populate it with the values from your original list. Perhaps not the most efficient solution as far as run-time and memory management is concerned, but certainly easy to code:

list<A*> list1;
list<const A*> list2;
for(list<A*>::iterator a=list1.begin(); a!=list1.end(); a++) list2.push_back(*a);
混浊又暗下来 2024-10-20 18:19:12

您必须创建列表的副本 - 它是一个按值传递参数。有一种相当简单的方法来创建副本,因为元素类型具有隐式转换:所有 STL 容器都可以从一对迭代器创建。因此,在您的情况下:

std::list<A*> src;
Foo(std::list<const A*>(src.begin(), src.end()));

这比需要的稍微困难一些,因为 STL 将范围表示为迭代器对,而 C++ 转换规则适用于单个对象。

You'll have to create a copy of the list - it's a pass-by-value argument. There's a fairly simple way to create a copy, since the element types have an implicit conversion: all STL containers can be created from a pair of iterators. So, in your case:

std::list<A*> src;
Foo(std::list<const A*>(src.begin(), src.end()));

This is slightly harder than it needs to be, because the STL represents ranges as pairs of iterators, and C++ conversion rules work on single objects.

深爱成瘾 2024-10-20 18:19:12

我相信你可以照原样通过。请记住,非常量类型可以传递给需要常量类型的对象,但反之则不然!

I believe you can pass it as it is. Remember that non-const types can be passed to something expecting a const type, but not the other way round!

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