Оператор Overloading [] для редкого вектора

Я не нашел readonly ключевое слово, пока я не нашел ReSharper, но я теперь использую его инстинктивно, специально для классов обслуживания.

readonly var prodSVC = new ProductService();
6
задан Thomas 6 September 2009 в 16:37
поделиться

3 ответа

Здесь может быть очень простой трюк, но в остальном я думаю, что оператор [] должен возвращать только то, что может быть присвоено из V (и преобразовано в V), а не обязательно V&. Итак, я думаю, вам нужно вернуть какой-то объект с перегруженным operator = (const V &) , который создает запись в вашем разреженном контейнере.

Вам нужно будет проверить, что функция Boost делает со своим шаблоном параметр, однако - определяемое пользователем преобразование в V влияет на то, какие цепочки преобразования возможны, например, предотвращая появление каких-либо дополнительных пользовательских преобразований в той же цепочке.

13
ответ дан 8 December 2019 в 05:22
поделиться

Не позволяйте неконстантному оператору и реализации возвращать ссылку, но прокси-объект. Затем вы можете реализовать оператор присваивания прокси-объекта, чтобы отличать доступ для чтения к operator [] от доступа для записи.

Вот некоторый набросок кода, чтобы проиллюстрировать идею. Этот подход некрасивый, но хорошо - это C ++. Программисты на C ++ не тратят время на участие в конкурсах красоты (у них тоже не будет шансов). ; -)

template <typename V, V Default>
ProxyObject SparseVector::operator[]( int i ) {
   // At this point, we don't know whether operator[] was called, so we return
   // a proxy object and defer the decision until later
   return ProxyObject<V, Default>( this, i );
}

template <typename V, V Default>
class ProxyObject {
    ProxyObject( SparseVector<V, Default> *v, int idx );
    ProxyObject<V, Default> &operator=( const V &v ) {
      // If we get here, we know that operator[] was called to perform a write access,
      // so we can insert an item in the vector if needed
    }

    operator V() {
      // If we get here, we know that operator[] was called to perform a read access,
      // so we can simply return the existing object
    }
};
9
ответ дан 8 December 2019 в 05:22
поделиться

Интересно, надежен ли этот дизайн.

Если вы хотите вернуть ссылку, это означает, что клиенты этого класса могут сохранить результат вызова operator [] в ссылке и читать / записывать в нее в любое более позднее время. Если вы не возвращаете ссылку и / или не вставляете элемент каждый раз при обращении к определенному индексу, как они могли это сделать? (Кроме того, у меня такое ощущение, что стандарт требует наличия соответствующего контейнера STL, обеспечивающего operator [] , чтобы этот оператор возвращал ссылку, но я не уверен в этом.)

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

std :: map решает эту проблему, указывая, что неконстантная версия этого оператора всегда вставляет элемент (и вообще не предоставляет версию const ).

Конечно, вы всегда можете сказать, что этот не стандартный контейнер STL, и оператор [] не возвращает простые ссылки, которые пользователи могут хранить. И, может быть, это нормально. Мне просто интересно.

вы всегда можете сказать, что этот не стандартный контейнер STL, и оператор [] не возвращает простые ссылки, которые пользователи могут хранить. И, может быть, это нормально. Мне просто интересно.

вы всегда можете сказать, что этот не стандартный контейнер STL, и оператор [] не возвращает простые ссылки, которые пользователи могут хранить. И, может быть, это нормально. Мне просто интересно.

1
ответ дан 8 December 2019 в 05:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: