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

C++ C++;如何将非常量列表传递给需要常量列表的函数,c++,constants,covariance,C++,Constants,Covariance,我有一个带签名的函数 void Foo(list<const A*>) void Foo(列表) 我想通过考试 list<A*> 列表 我该怎么做? (请注意-列表不是固定不变的,只有列表中的成员)我相信您可以按原样传递它。请记住,可以将非常量类型传递给需要常量类型的对象,但不能反过来传递 问题是,即使T*可以隐式转换为T const*,模板系统也没有“意识到”这一点,因此whatever和whatever是完全不相关的类型,并且没有从一个隐式转换到另一个 为了避

我有一个带签名的函数

void Foo(list<const A*>)
void Foo(列表)
我想通过考试

list<A*>
列表
我该怎么做?
(请注意-列表不是固定不变的,只有列表中的成员)

我相信您可以按原样传递它。请记住,可以将非常量类型传递给需要常量类型的对象,但不能反过来传递

问题是,即使
T*
可以隐式转换为
T const*
,模板系统也没有“意识到”这一点,因此
whatever
whatever
是完全不相关的类型,并且没有从一个隐式转换到另一个

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


这可能会为您省去不少麻烦--
列表
很少是容器的好选择,因此有一个很大的机会,有一天您会希望从
列表
更改为
向量
或者
deque
,如果您将函数设置为泛型,您可以在不重写函数的情况下执行此操作。

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

list<A*> list1;
list<const A*> list2;
for(list<A*>::iterator a=list1.begin(); a!=list1.end(); a++) list2.push_back(*a);
列表列表1;
清单2;
对于(list::iterator a=list1.begin();a!=list1.end();a++)list2.push_back(*a);

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

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

这比它需要的要稍微困难一些,因为STL表示作为迭代器对的范围,C++转换规则对单个对象工作。p> 你有没有试着按原样传递列表?如果是这样,你得到了什么?@Oswald,一些可怕的模板转换错误类似于

错误:请求将“std::list”转换为非标量类型“std::list”
?@vondip-你能告诉我们错误消息吗?另外,这是一个模板函数,还是一个具体类型?最后,您确定您是通过值而不是通过引用传递的,对吗?关于使用迭代器的好建议。但是,
list::iterator
list::iterator
(或
const_iterator
)之间没有关系,因此使用迭代器的函数必须将其作为模板参数。如果无法更改函数签名,从列表复制到新列表将是唯一的解决方案?@Oswald:可能在这种非常特殊的情况下,
reinterpret\u cast
会起作用。然而,除了通过迭代器抽象列表之外,没有干净的解决方案。在C#4中有协变泛型,它可以非常优雅地解决这类问题(并为强大的抽象打开了大门)。list和list实际上是两种不同的非常量类型。