C ++ Как передать список неконстант в функцию, требующую список констант - PullRequest
12 голосов
/ 24 января 2011

У меня есть функция с подписью

void Foo(list<const A*>)

и я хочу передать его

list<A*>

Как мне это сделать? (обратите внимание - список не является постоянным, только член списка)

Ответы [ 4 ]

19 голосов
/ 24 января 2011

Проблема, с которой вы столкнулись, заключается в том, что, хотя T * можно неявно преобразовать в T const *, система шаблонов не «знает» об этом, поэтому whatever<T *> и whatever<T const *> - это совершенно не связанные типы и нет неявного преобразования из одного в другое.

Чтобы избежать проблемы, я бы, вероятно, вообще не передавал коллекцию. Вместо этого я бы сделал так, чтобы функция брала пару итераторов. list<A *>::iterator может быть неявно преобразовано в list<A *>::const_iterator. Впрочем, я бы, вероятно, сделал функцию шаблоном, чтобы он мог принимать итераторы произвольного типа.

Это, скорее всего, избавит вас от многих неприятностей - list редко является хорошим выбором контейнера, так что есть очень большой шанс, что когда-нибудь вы захотите перейти с list<A *> на vector<A *> или, возможно, deque<A *> - и если вы сделаете свою функцию универсальной, вы сможете сделать это без переписывания функции вообще.

0 голосов
/ 25 января 2011

Вам нужно будет создать копию списка - это аргумент передачи по значению. Существует довольно простой способ создания копии, поскольку типы элементов имеют неявное преобразование: все контейнеры STL могут быть созданы из пары итераторов. Итак, в вашем случае:

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

Это немного сложнее, чем нужно, потому что STL представляет диапазоны в виде пар итераторов, а правила преобразования C ++ работают с отдельными объектами.

0 голосов
/ 25 января 2011

Вы можете просто создать новый список и заполнить его значениями из исходного списка.Возможно, не самое эффективное решение с точки зрения времени выполнения и управления памятью, но, безусловно, легко кодируемое:

list<A*> list1;
list<const A*> list2;
for(list<A*>::iterator a=list1.begin(); a!=list1.end(); a++) list2.push_back(*a);
0 голосов
/ 24 января 2011

Я верю, что вы можете передать это как есть. Помните, что неконстантные типы могут быть переданы чему-то, ожидающему константный тип, но не наоборот!

...