Вернуть константный вектор константных общих указателей на константные объекты

Учитывая следующий класс, основанный на контейнерах общих указателей,

class Foo;

class Bar {
public:
// ...
const std::vector<boost::shared_ptr<const Foo> >& getFoos() const { return foos_; }
private:
std::vector<boost::shared_ptr<Foo> > foos_;
};

который не будет компилироваться, потому что

invalid initialization of reference of type ‘const std::vector<boost::shared_ptr<const Foo>, std::allocator<boost::shared_ptr<const Foo> > >&’ from expression of type ‘const std::vector<boost::shared_ptr<Foo>, std::allocator<boost::shared_ptr<Foo> > >’

foos_ член должен указывать на изменчивый Foo объекты для внутреннего использования Bar объект, но я не хочу вызова клиентского кода getFoos() чтобы иметь возможность что-либо изменить.

Удаление const классификатор из Foo в getFoos() возвращаемый тип исправляет это. Тем не менее, я понимаю, что пока std::vector распространяет свою константность своим элементам, boost::shared_ptr не делает ничего подобного объекту, на который он указывает (естественно). Таким образом, мне кажется getFoos() больше не наблюдает его const квалификатор (хотя компилятор не жалуется), потому что клиентский код может изменить Foo объекты, на которые указывают общие указатели, возвращаются.

Я прав? Если так, есть ли способ написать getFoos() чтобы он возвращал константный вектор константных ссылок на константные объекты без копирования?

4

Решение

Я могу ошибаться, но я действительно не думаю, что вы можете достичь этого.

shared_ptr<Foo> может стать shared_ptr<const Foo> только путем строительства нового экземпляра shared_ptr<const Foo>

Ссылка на shared_ptr<Foo> не может стать ссылкой на shared_ptr<const Foo>просто потому что они два разные типы.

Здесь вы пытаетесь получить ссылку на vector<shared_ptr<Foo>> в форме const vector<shared_ptr<const Foo>>,

Первый const отлично в порядке. Так как можно назначить ссылку на тот же тип ссылки с помощью квалификатора const.

Но второе const нет, так как вы буквально пытаетесь преобразовать ссылку на вектор Type A к ссылке на вектор Type B,

3

Другие решения

Вместо возврата std::vector<...> const&что насчет возврата диапазона? Диапазон pair итераторов некоторого вида. В этом случае ваши итераторы будут std::shared_ptr<const foo>, Вы можете сделать это, написав быстрый адаптер итератора, который внутренне перебирает const_iterator в std::shared_ptr<foo>, но возвращает их как std::shared_ptr<const foo>,

Большинство операций, которые вы хотите выполнить на const vector может быть выполнен на range произвольного доступа const_iterators.

2

Вы можете вернуть const shared_ptr<Foo>* указатель вместо вектора и использование явного уродливого приведения в стиле C для преобразования foos_.data() во все, что вы хотите.

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

0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector