тупой вопрос, наверное, но вот не знаю как лучше сделать.
есть старый код, который переделываем, чтобы вместо скалярной величины можно было засунуть массив.
надо чтобы 0.0 перешел в массив нулей.
class arrayData
{
...
// from 0.0 to all 0.0
arrayData(const double null)
{
m_data.resize(m_size);
std::fill(m_data.begin(), m_data.end(), null);
}
...
}
// используем: 0.0 плавно переходит в массив нулей.
// template<typename typeData>
typeData calculate<typeData>::engine()
{
...
typeData result = condition ? f(x) : 0.0;
...
}
надо чтобы calculate для double работал.
в этом решение не нравится что все double легко переводятся в нулевой массив. можно ли как это обезопасить это решение.
Здравствуйте, Аноним, Вы писали:
А>тупой вопрос, наверное, но вот не знаю как лучше сделать.
Вопрос не тупой, а криво сформулированный.
Перевожу на понятный язык.
Есть функция calculate над скалярными данными.
Хочется обобщить её, чтобы она работала не только со скалярами, но и с векторами (некоей известной размерности).
Встречные вопросы, для полноты картины:
Размерность векторов известна заранее?
— на стадии компиляции (функция параметризована типом: скаляр, K-мерный вектор, N-мерный вектор, и т.д.)
— на стадии вычисления (функция параметризована типом: скаляр либо вектор; в случае вектора размерность берётся как аргумент функции)
Функция имеет дело с одной или разными размерностями одновременно?
Кроме скаляров и векторов что-нибудь ещё может встретиться? ну там, матрицы...
А пока ответы я не узнал, предложу такой простенький вариант
К>Вопрос не тупой, а криво сформулированный.
К>Перевожу на понятный язык. К>Есть функция calculate над скалярными данными. К>Хочется обобщить её, чтобы она работала не только со скалярами, но и с векторами (некоей известной размерности).
да! абсолютно так!
К>Встречные вопросы, для полноты картины: К>Размерность векторов известна заранее? К>- на стадии компиляции (функция параметризована типом: скаляр, K-мерный вектор, N-мерный вектор, и т.д.) К>- на стадии вычисления (функция параметризована типом: скаляр либо вектор; в случае вектора размерность берётся как аргумент функции) К>Функция имеет дело с одной или разными размерностями одновременно? К>Кроме скаляров и векторов что-нибудь ещё может встретиться? ну там, матрицы...
вектор всегда имеет размерность 10 и он известен уже на этапе компиляции. саму функцию мы используем в одном месте, чтобы посчитать скаляр double, а в другом хотим использовать для вектора. теоретически могут быть и матрицы, но пока это совсем не нужно.
Здравствуйте, avalanche2010, Вы писали:
A>вектор всегда имеет размерность 10 и он известен уже на этапе компиляции. саму функцию мы используем в одном месте, чтобы посчитать скаляр double, а в другом хотим использовать для вектора. теоретически могут быть и матрицы, но пока это совсем не нужно.
Я так понимаю, арифметика над векторами — покомпонентная. Тогда можно взглянуть в сторону std::valarray. Над ним уже определены всякие операции.
Дальнейшие пути:
1) Использовать только valarray<double> двух размерностей — 1 и 10. Параметризовать (хоть в шаблоне, хоть в рантайме) функцию этой размерностью.
2) Параметризовать функцию типом double / valarray<double> и словарём примитивов (нулевое значение 0.0 / valarray<double>(10), единичное значение 1 / valarray<double>(1.0,10), и т.д.)
3) Написать собственный класс, унаследованный от valarray, который конструирует себя с правильной размерностью. Но, боюсь, писанины и несовместимостей здесь будет очень много.
Очевидно, не устроит — если в роли typeData выступает вектор произвольной размерности std::vector или std::valarray.
Размерность нужно каким-то способом пригвоздить.
Например, сделать класс, оборачивающий (наследующийся от) стандартного вектора. Пусть он в своём дефолтном или скалярном конструкторе должным образом создаёт вектор.
Здравствуйте, Кодт, Вы писали:
К>Очевидно, не устроит — если в роли typeData выступает вектор произвольной размерности std::vector или std::valarray. К>Размерность нужно каким-то способом пригвоздить. К>Например, сделать класс, оборачивающий (наследующийся от) стандартного вектора. Пусть он в своём дефолтном или скалярном конструкторе должным образом создаёт вектор.
Так а вариант с traits(dims) не лучше, получается dims надо параметром передавать. Лучше уж обернуться.
Ну если уж на то пошло, так для контейнеров лучше бы и функцию переписать с передачей параметра по ссылке.
Здравствуйте, sokel, Вы писали:
S>Здравствуйте, Кодт, Вы писали:
К>>Очевидно, не устроит — если в роли typeData выступает вектор произвольной размерности std::vector или std::valarray. К>>Размерность нужно каким-то способом пригвоздить. К>>Например, сделать класс, оборачивающий (наследующийся от) стандартного вектора. Пусть он в своём дефолтном или скалярном конструкторе должным образом создаёт вектор.
S>Так а вариант с traits(dims) не лучше, получается dims надо параметром передавать. Лучше уж обернуться. S>Ну если уж на то пошло, так для контейнеров лучше бы и функцию переписать с передачей параметра по ссылке.
Вообще что то я торможу, изначально вариант с конструктором как раз и описан
Здравствуйте, sokel, Вы писали:
S>Так а вариант с traits(dims) не лучше, получается dims надо параметром передавать. Лучше уж обернуться.
"Лучше" зависит от того, как эта функция используется.
Если в системе есть ровно два типа данных — скаляр и десятимерный вектор, то конечно, удобно ввести класс "десятимерный вектор" (или N-мерный, где N — параметр шаблона). Шаблон функции параметризуется этим типом, и всё.
Если же предполагается, что выбор размерности происходит в рантайме (или этих размерностей просто слишком много, чтобы плодить инстансы классов и функций) — то можно сделать нешаблонную функцию, аргумент которой — размерность вектора.