Передача указателя QVector в качестве аргумента
1) Я хочу передать указатель на QVector в функцию, а затем сделать что-то с ним. Я попробовал это:
void MainWindow::createLinearVector(QVector<float> *vector, float min, float max )
{
float elementDiff=(max-min)/(vector->size()-1);
if(max>min) min -= elementDiff;
else min += elementDiff;
for(int i=0; i< vector->size()+1 ; i++ )
{
min += elementDiff;
*(vector+i) = min; //Problematic line
}
}
Однако компилятор дает мне "нет совпадения для оператора =" для *(vector+i) = min;
линия. Как лучше всего выполнять подобные действия на QVector?
2) Предполагается, что функция линейно распределяет значения по вектору для графика, как работает оператор matlab: например, вектор (a:b:c). Какой самый простой и лучший способ выполнить такие вещи в Qt?
РЕДАКТИРОВАТЬ:
С помощью отсюда начальная проблема решена.:)
Я также улучшил метод сам по себе. Точность может быть значительно улучшена с помощью линейной интерполяции вместо нескольких сложений, как описано выше. При многократном сложении накапливается ошибка, которая в значительной степени устраняется путем линейной интерполяции.
Кстати, оператор if в первой функции был ненужным и его можно было удалить, просто немного переставив вещи даже в методе множественного сложения.
void MainWindow::createLinearVector(QVector<double> &vector, double min, double max )
{
double range = max-min;
double n = vector.size();
vector[0]=min;
for(int i=1; i< n ; i++ )
{
vector[i] = min+ i/(n-1)*range;
}
}
Я подумал об использовании некоторого расширенного цикла для этого, но будет ли это более практичным? Например, с циклом foreach мне все равно придется увеличивать некоторую переменную для правильной интерполяции? А также сделать условие для пропуска первого элемента?
3 ответа
Я хочу разместить поплавок в определенном месте в QVector.
Тогда используйте это:
(*vector)[i] = min; //Problematic line
Вектор - это указатель на QVector, *vector
будет QVector, который может быть обозначен с [i]
как и любой QVector. Тем не менее, из-за старшинства, скобки нужны для правильного порядка операций.
Я думаю, сначала вам нужно использовать итератор Mutable для этого: ссылка на Qt doc
Что-то вроде этого:
QMutableVectorIterator<float> i(vector);
i.toBack();
while (i.hasPrevious())
qDebug() << i.{your code}
Правильно, поэтому нет смысла использовать здесь указатель QVector. Вот причины этого:
Использование ссылки на параметр метода должно быть более подходящим для C++, если неявное совместное использование недостаточно быстро для вас.
Хотя в большинстве случаев вам даже не понадобится ссылка, когда вы просто передаете аргументы, не возвращая результат в том же аргументе (то есть в выходном аргументе). Это потому, что *QVector неявно используется совместно, и копирование происходит только для записи в соответствии с документацией. К счастью, в обоих случаях синтаксис будет одинаковым для вызова и внутренней реализации метода, поэтому его легко переключать с одного на другой.
Использование "умных" указателей предпочтительнее, чем "сырых", но, на мой взгляд, и то, и другое - излишне сложные решения
Итак, я хотел бы предложить изменить ваш код в это:
void MainWindow::createLinearVector(QVector<float> &vector, float min, float max)
{
float elementDiff = (max-min) / (vector.size()-1);
min += ((max>min) ? (-elementDiff) : elementDiff)
foreach (float f, vector) {
min += elementDiff;
f = min;
}
}
Обратите внимание, что я исправил следующие вещи в вашем коде:
Параметр ссылочного типа в отличие от указателя
"->" разрешение участника до "." соответственно
Тройная операция вместо неестественного if/else в этом случае
Еогеасп Qt вместо индексации низкого уровня в этом случае исходная точка становится спорным
Тогда вы бы вызвали метод из вызывающей стороны:
createLinearVector(vector, fmin, fmax);