2015-10-28 4 views
2

Предположим, что у меня есть переменная-член std::vector<std::string> в классе, и я хочу вернуть ее из функции-члена в качестве неизменяемого представления, используя комбинацию gsl::array_view и gsl::cstring_view. К сожалению, следующий не компилируется:gsl :: array_view <const gsl :: cstring_view <>> from std :: vector <std::string>

class C { 
public: 
    gsl::array_view<const gsl::cstring_view<>> getVectorOfStrings() const 
    { 
     return _vectorOfStrings; 
    } 

private: 
    std::vector<std::string> _vectorOfStrings; 
}; 

Причиной этого является то, что нет контейнер cstring_view что array_view может быть создан из. Поэтому мой вопрос: есть ли способ использовать такую ​​конструкцию, явно не добавляя что-то вроде члена типа std::vector<gsl::cstring_view<>>, что явно нежелательно?

Редактировать

Мне кажется, что такие «трансформирующие» взгляды могут быть более общего пользования. Рассмотрите наличие vector владеющих указателей, таких как std::vector<std::shared_ptr<T>>, которые я хотел бы предоставить пользователю класса в виде array_view необработанных указателей: gsl::array_view<const T*> без раскрытия моего подхода к реализации, определенного для реализации. Мысли?

+0

С этим теоретическим 'array_view'' cstring_view ', которому принадлежит коллекция' cstring_view ', существование которой требуется из существования' array_view' 'cstring_view's? – jaggedSpire

+0

@jaggedSpire Ну, это именно то, что я сказал в последнем абзаце моего вопроса. Но, возможно, есть способ какой-то лениво-оценкой 'array_view', который будет конвертировать любое значение' string_view'-compatible-array в 'string_view' по запросу. Возможно, я мог бы написать такое, но я подумал, что, возможно, есть лучший способ. Таким образом, этот вопрос: – Rostislav

+0

ах. Если вы хотите обратиться к коллекции, не имеющей права собственности, которая может быть легко конвертируемой в 'cstring_view's, могу ли я спросить, почему избегается' array_view' 'std :: strings'? – jaggedSpire

ответ

1

По определению представления обычно предоставляют только ссылки на существующие объекты. В результате нет никакого способа создать нормальный array_view<const cstring_view<>> без предварительного создания соответствующего контейнера, например, например. a vector<const cstring_view<>>.

Однако вы можете создать свою собственную специализацию для gsl::array_view<const cstring_view<>>, которая создает запрос cstring_view<> по требованию (при вызове оператора индекса и при разыменовании итератора). Хотя это избавит вас от динамического распределения памяти и уменьшит объем памяти по сравнению с наивным подходом, в большинстве случаев мне не нужна дополнительная сложность.

Если вы хотите следовать обобщенному подходу, как описано в вашем редактировании, вы можете посмотреть на boost::transform_iterator - либо для непосредственного использования, либо в качестве вдохновения для вашего собственного обобщенного класса transform_array_view (который, я уверен, быть приветствующим дополнением к gsl или boost).

+0

Ну, после нескольких исследований мне кажется, что 'array_view' (или' span', как он называется сейчас) просто не подходит дизайном для этой цели. 'span' ожидает непрерывного хранения некоторого типа данных, поэтому в основном его можно обработать вызовом' data() '. В конце я использовал 'any_range' с адаптером range. Я все еще думаю, что это может быть интересная дискуссия, поэтому я подниму дискуссию о github GSL. – Rostislav

Смежные вопросы