В нашем продукте много точек/векторов, прямо на каждом шагу. Т.е. тройки даблов. Могут быть отдельные, могут быть массивы.
Продукт большой, разработчиков много, стандарта жёсткого нет и наличествует несколько форматов передачи данных.
С одной стороны, чаще всего встречается передача через голые указатели. С другой стороны, их надо чуток обработать и, в частности, имеется класс для работы с вектором SuperPooperVector3, который умеет все что нужно. Бинарное представление этого класса простое — 3 дабла и все.
Т.е. некоторый участок памяти из 3 даблов считаем как объект класса (с совпадающем представлении в памяти) и используем его методы.
Возможная реализация преобразователя
const Vector3& AsVector3(const double* v)
{
*reinterpret_cast<const Vector3D*>( v );
}
Vector3& AsVector3(double* v)
{
*reinterpret_cast<Vector3D*>( v );
}
Понятно, что это некошерно. Понятно, что в общем случае это совсем зло-зло. Но если очень хочется... в отдельных случаях...
Здравствуйте, RikkiTikkiTavi, Вы писали: RTT>Какого будет мнение состоятельных кротов?
Я, как иструмент меж-коллекционного взаимодействия (то есть для всего, что можно представить как последовательную коллекцию одинаковых типов) использую std::initializer_list. То есть у математического вектора есть констуктор по std::initializer_list<double>, и функция list() возвращающая std::initializer_list<double> с его членами.
Здравствуйте, RikkiTikkiTavi, Вы писали:
RTT>Здраствуйте!
RTT>Хочется немного хулиганства...
RTT>В нашем продукте много точек/векторов, прямо на каждом шагу. Т.е. тройки даблов. Могут быть отдельные, могут быть массивы.
RTT>Продукт большой, разработчиков много, стандарта жёсткого нет и наличествует несколько форматов передачи данных.
Надо что-то менять в консерватории. Начать следует с руководителя проекта.
Когда проект большой и много разработчиков, то надо вводить стандарты на интерфейсы и представление данных.
Для этого делается небольшой исследовательский проект, на котором отрабатывается наиболее подходящие решения, которые потом жёстко фиксируются в основном проекте.
Здравствуйте, RikkiTikkiTavi, Вы писали:
RTT> имеется класс для работы с вектором SuperPooperVector3, который умеет все что нужно. Бинарное представление этого класса простое — 3 дабла и все. RTT>Какого будет мнение?
Для standard-layout структур это разрешено. Даже в стандарте есть пример с reinterpret_cast и complex<T>, который, очевидно, отличается от твоего примера лишь тем, что у тебя три числа, а не два.
Хотя с массивом таких гарантий нет — то есть нельзя сначала сделать каст к указателю на массив векторов, а потом его индексировать, а нужно каждый раз делать новый каст:
Vector3* p = &AsVector3(vertices+i*3);
use(p[0]) // можно
use(p[1]) // нельзя
но в то же время
use(AsVector3(vertices+(i+0)*3)); // можно
use(AsVector3(vertices+(i+1)*3)); // можно
Хотя практически везде будут оба варианта работать пока не встретится где-нибудь, например, агрессивное выравнивание (тогда первый код сломается, а второй гарантированно продолжит работать).
RTT> имеется класс для работы с вектором SuperPooperVector3, который умеет все что нужно
А не рассматривался вариант с классом SuperPooperVector3View, который также умеет всё что нужно, но не владеет данными, а содержит лишь содержит ссылку на первый double? Тогда такой класс можно без всяких reinterpret_cast сконструировать как из SuperPooperVector3, так и из голого массива.
W>Я, как иструмент меж-коллекционного взаимодействия (то есть для всего, что можно представить как последовательную коллекцию одинаковых типов) использую std::initializer_list. То есть у математического вектора есть констуктор по std::initializer_list<double>, и функция list() возвращающая std::initializer_list<double> с его членами.
Мы пока ограничены VS2012 и старше, но интересно
Здравствуйте, watchmaker, Вы писали: W>Хотя с массивом таких гарантий нет — то есть нельзя сначала сделать каст к указателю на массив векторов, а потом его индексировать, а нужно каждый раз делать новый каст:
W>Vector3* p = &AsVector3(vertices+i*3);
W>use(p[0]) // можно
W>use(p[1]) // нельзя
W>
W>... W>Хотя практически везде будут оба варианта работать пока не встретится где-нибудь, например, агрессивное выравнивание.
Да, с интерпретацией массива выходит явное зло, хотя я и не подразумевал пока...
RTT>> имеется класс для работы с вектором SuperPooperVector3, который умеет все что нужно W>А не рассматривался вариант с классом SuperPooperVector3View, который также умеет всё что нужно, но не владеет данными, а содержит лишь содержит ссылку на первый double? Тогда такой класс можно без всяких reinterpret_cast сконструировать как из SuperPooperVector3, так и из голого массива.
Да, пожалуй, это будет значительно лучше
Хм, мощно!
Хотя местами не все понимаю, но в общем понятно, что очевидное решение с полиморфизмом заменяем на более эффективное.
Единственное, что функционал навязывается введением глобальных методов, а хотелось бы методы класса.