Re[8]: ссылка на локальный вектор
От: Erop Россия  
Дата: 17.05.16 04:53
Оценка:
Здравствуйте, sci_reseacher, Вы писали:

_>в одном классе мне нужен std::vector<T>, в другом T*, т.к. это две разные реализации класса, работающие на разных устройствах --- а пользователь их может выбирать.


А что мешает доставать float* из вектора просто?
Зачем хранить две идентичные копии данных?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[9]: ссылка на локальный вектор
От: sci_reseacher  
Дата: 17.05.16 06:18
Оценка:
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, sci_reseacher, Вы писали:


_>>в одном классе мне нужен std::vector<T>, в другом T*, т.к. это две разные реализации класса, работающие на разных устройствах --- а пользователь их может выбирать.


E>А что мешает доставать float* из вектора просто?

E>Зачем хранить две идентичные копии данных?

Технологии, используемые в классе с полем T* не могут работать с vector<T> и предоставляют для чтения из некоторой области памяти T* ...
Отредактировано 17.05.2016 6:21 sci_reseacher . Предыдущая версия .
Re[2]: ссылка на локальный вектор
От: sci_reseacher  
Дата: 17.05.16 07:07
Оценка:
Здравствуйте, Erop, Вы писали:

Задачка такая была.

Есть некоторый класс A который как-то вычисляет (work) значения (например float) некоторого вектора X
struct Base {
    virtual const std::vector<float> & setX() = 0;
};

struct A: public Base {
   std::vector<float> X;
   A(){ X.resize(10,55);}
   void work() { fill( X.begin(), X.end(), 25 );  }
   const std::vector<float> & setX() { return X; }
};

и работать с ним было очень удобно: поставил ссылку на вектор X и читаешь значения когда нужно:
A a;
const std::vector<float> & x = a.setX();
copy( x.begin(), x.end(), ostream_iterator<float>( cout, " "));
a.work();
copy( x.begin(), x.end(), ostream_iterator<float>( cout, " "));




Появилась необходимость в классе B, который использует совсем другие технологии расчета и хранения данных (с std::vector не работает),
но предоставляет указатель float * для обращения к непрерывному участку памяти. Хотелось бы не меняя интерфейс и логику
всех модулей и программ в классе B сделать setX такой же как и в классе A
struct B: public Base {
   float* X;
   int size;
   B(){ /* .. */ }
   void work() { /* hard calc. for X */  }
   const std::vector<float> & setX() { return /* ..*/; }
};


Похоже, что единственный вариант, сделать в B() поле std::vector или в Base его перенести.


E>Здравствуйте, sci_reseacher, Вы писали:


_
E>1) А зачем tmp не временный? Можно же так:
E>
struct A
E>{
E>    float* X_;
E>    int size;
E>    vector<float> getX(){
E>        return vector<float> tmp(X_,X_+size);
E>    }
    
_>>};
E>

E>2) Зачем возвращать ссылку? Можно же просто копию, в надежде на RVO, а если объект временным делать нельзя, то NRVO
E>3) Если С++11 и позже, то возвращаемое значение можно через мув-конструктор получать, что недорого
E>4) Главное, зачем вообще этот массив float'ов копировать в вектор? Можно же просто возвращать два указателя, в качестве итераторов?
Re[3]: ссылка на локальный вектор
От: jazzer Россия Skype: enerjazzer
Дата: 17.05.16 08:34
Оценка:
Здравствуйте, sci_reseacher, Вы писали:


_>Появилась необходимость в классе B, который использует совсем другие технологии расчета и хранения данных (с std::vector не работает),

_>но предоставляет указатель float * для обращения к непрерывному участку памяти. Хотелось бы не меняя интерфейс и логику

Переделай интерфейс на array_view.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[10]: ссылка на локальный вектор
От: Erop Россия  
Дата: 17.05.16 09:08
Оценка:
Здравствуйте, sci_reseacher, Вы писали:

_>Технологии, используемые в классе с полем T* не могут работать с vector<T> и предоставляют для чтения из некоторой области памяти T* ...


То есть данными владеют "технологии"? Или ты им буфер предоставляешь?

18.05.16 12:10: Удалено модератором из 'C/C++'.
18.05.16 12:10: Восстановлено модератором.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[5]: ссылка на локальный вектор
От: B0FEE664  
Дата: 17.05.16 10:23
Оценка: 1 (1)
Здравствуйте, sci_reseacher, Вы писали:

_>нужно сделать наследников D и C класса B, таких, что в одном данные хранятся в std::vector<T>, а в другом классе T* указывает на эти данные.

  Скрытый текст
_>
_>struct B {
_>    virtual const vector<float> &  getX() = 0 ;
_>};


_>struct C: public B {
_>    float *X;
_>    int size;
_>//    vector<float>  getX(){
_>//    vector<float> tmp(X,X+size);
_>//    return tmp;
_>//    }
_>};

_>struct D: public B {
_>    vector<float> X;
_>    const vector<float>  & getX(){
_>        return X;
_>    }
_>};
_>

_>наверное лучший вариант переделать базовый класс
_>

_>struct B {
_>    virtual vector<float> getX() = 0 ;
_>};

  Скрытый текст
_>struct C: public B {
_>    float *X;
_>    int size;

_>    virtual vector<float> getX(){
_>        vector<float> tmp(X,X+size);
_>        return tmp;
_>    }
_>};

_>struct D: public B {
_>    vector<float> X;
_>    virtual vector<float>  getX(){
_>        return X;
_>    }
_>};
_>

_>и использовать так
_>
_>const vector<float> & w = d.getX(); // только вот здесь для D d нет ли лишней копии вектора? всегда работает return value optimization?
_>


Я сомневаюсь, что это лучший вариант, т.к. это потеря и в скорости, и в расходе памяти.
Смотрите: вам нужно к объектам разной природы предоставить единый интерфейс.
Возвращать vector — значит конвертировать один тип (T*) в другой — std::vector<T>. Это самый тривиальный способ, но есть и другие подходы.
Например, выделить у T* и std::vector<T> общий интерфейс и дать к нему доступ.
Общим специфичным интерфейсом для T* и std::vector<T> является индексный доступ, поэтому можно в базовом классе вместо
struct B
{
    virtual vector<float> getX() = 0 ;
};

отдать вот такой интерфейс:
struct B
{
    virtual float  getElementX(size_t index) = 0 ;
    virtual size_t getSizeX() = 0;
};


Это незначительный проигрыш в скорости, но без потерь в памяти. Если в этой иерархии у вас не планируется третий класс, элементы которого будут хранится в контейнере не допускающим индексный доступ, то на этом можно остановится.
И каждый день — без права на ошибку...
Re[4]: ссылка на локальный вектор
От: sci_reseacher  
Дата: 17.05.16 15:15
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Здравствуйте, sci_reseacher, Вы писали:



_>>Появилась необходимость в классе B, который использует совсем другие технологии расчета и хранения данных (с std::vector не работает),

_>>но предоставляет указатель float * для обращения к непрерывному участку памяти. Хотелось бы не меняя интерфейс и логику

J>Переделай интерфейс на array_view.


имеется ввиду вот эта обертка ? или есть еще какой-то wrapper?
Re[5]: ссылка на локальный вектор
От: jazzer Россия Skype: enerjazzer
Дата: 17.05.16 15:20
Оценка:
Здравствуйте, sci_reseacher, Вы писали:

_>имеется ввиду вот эта обертка ? или есть еще какой-то wrapper?


Да, эта вполне подойдет. А в следующем стандарте или через один будет встроенный std::array_view
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[6]: ссылка на локальный вектор
От: sci_reseacher  
Дата: 17.05.16 15:26
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Здравствуйте, sci_reseacher, Вы писали:


_>>имеется ввиду вот эта обертка ? или есть еще какой-то wrapper?


J>Да, эта вполне подойдет. А в следующем стандарте или через один будет встроенный std::array_view


если уж переделывать интерфейс базового класса, то а вот я не пойму: чем же будет лучше возвращать array_view<T>, а не T*?

float* getX(){ };



P.S. извиняюсь, не знаю как удалить сообщение, все, понял ... интерфейс вектора там повторяется и модули работающие с редактируемым классом не нужно править
Отредактировано 17.05.2016 15:35 sci_reseacher . Предыдущая версия .
Re[6]: ссылка на локальный вектор
От: sci_reseacher  
Дата: 18.05.16 06:35
Оценка:
вот здесь теперь можно быть уверенным, что всегда по ссылке ссылкам ref_a, ref_b ... будет доступен актуальный внутренний "array" на чтение без лишних "телодвижений" (копирования приводящего к расходу памяти и времени)?

struct A {
    std::vector<float> X;
    A(){ X.resize(10,5);}
    void work(void) { std::fill(X.begin(),X.end(),6); }
    arv::array_view<float>  getX(){
        return X;
    }
 };

struct B {
    float* X;
    B(){ X = new float[10];}
    void work(void) { for(int i=0; i<10; ++i) X[i] = i; }
    arv::array_view<float>  getX(){
        return {&X[0],10};
    }
 };

struct C {
    std::valarray<float> X;
    C(){ X.resize(5);}
    void work(void) { X += 3.14; }
    arv::array_view<float>  getX(){
        return {&X[0],X.size()};
    }
 };


A a;
const arv::array_view<float> & ref_a = a.getX();

B * b = new B;
const arv::array_view<float> & ref_b = b->getX();




Здравствуйте, jazzer, Вы писали:

J>Здравствуйте, sci_reseacher, Вы писали:


_>>имеется ввиду вот эта обертка ? или есть еще какой-то wrapper?


J>Да, эта вполне подойдет. А в следующем стандарте или через один будет встроенный std::array_view
Re[7]: ссылка на локальный вектор
От: jazzer Россия Skype: enerjazzer
Дата: 18.05.16 07:11
Оценка:
Здравствуйте, sci_reseacher, Вы писали:

_>вот здесь теперь можно быть уверенным, что всегда по ссылке ссылкам ref_a, ref_b ... будет доступен актуальный внутренний "array" на чтение без лишних "телодвижений" (копирования приводящего к расходу памяти и времени)?


Да. И нет необходимости создавать константные ссылки, храни их по значению просто.

З.Ы. И не топ-пости
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[9]: ссылка на локальный вектор
От: _hum_ Беларусь  
Дата: 18.05.16 10:27
Оценка:
Здравствуйте, Ops, Вы писали:

Ops>Здравствуйте, uzhas, Вы писали:


U>>или обратись к Стандарту

Ops>Не наш случай. Сей адепт интернет-толкований и научного тыка по компиляторам стандарт не признает.

я стандарт избегаю, потому что он написан скорее языком для разработчиков компиляторов, чем для простых пользователей. к тому же очень много исключений, замечаний, нюансов, в которых приходится кропотливо разбираться.
в этом плане ресурс cpp.reference, по-моему, делает хорошее дело — пытается стандарт изложить человеческим языком. другое дело, что у них не всегда это корректно получается сделать.
Re[10]: ссылка на локальный вектор
От: Ops Россия  
Дата: 18.05.16 10:39
Оценка:
Здравствуйте, _hum_, Вы писали:

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

Чего думать? Трясти надо! © Анекдот.
__>в этом плане ресурс cpp.reference, по-моему, делает хорошее дело — пытается стандарт изложить человеческим языком. другое дело, что у них не всегда это корректно получается сделать.
Хорошее, хорошее дело он делает. Но он не первоисточник, и в спорных случаях его мнение 10-е.
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
Re[5]: ссылка на локальный вектор
От: Igore Россия  
Дата: 19.05.16 14:47
Оценка:
Здравствуйте, sci_reseacher, Вы писали:

_>>>А как можно вернуть ссылку на std::vector<float> в данной ситуации, когда имеется float *?

U>>зачем вам ссылка нужна? какая задача? возвращайте по значению
_>нужно сделать наследников D и C класса B, таких, что в одном данные хранятся в std::vector<T>, а в другом классе T* указывает на эти данные.
А нельзя относледовать D от C?

struct B {
    virtual const vector<float> &  getX() = 0 ;
};

struct D: public B {
    vector<float> X;
    const vector<float>& getX(){
    return X;
    }
};

struct C: public D {
    float *X;
    int size;
    void update() {
       X = X.data();
       size = X.size();
    }
};
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.