Изменение конструктора вектора усиления - PullRequest
2 голосов
/ 06 декабря 2011

Я пытаюсь изменить поведение конструктора вектора BOOST uBLAS, и мне было интересно, как это лучше всего сделать. Я хочу инициализировать компоненты (координаты) 2D вектора с помощью конструктора, например:

Вместо:

typedef boost::ublas::vector BoostVector;

double x=1;
double y=0.7;

BoostVector<double> v(2);
v(1) = x; v(2) = y; //x and y are vector components/co-ordinates

Я хочу иметь возможность указать x и y в конструкторе.

BoostVector<double> v(x,y);

Я думаю, что мог бы создать новый класс, который предоставляет интерфейс для этого, либо содержанием, либо наследованием от класса векторов наддува, но я довольно плохо знаком с C ++ и не уверен в лучшем способе сохранить функциональность вектора наддува. Тем более, что я не хочу вмешиваться в оптимизацию шаблонных выражений, используемую векторным классом uBLAS. Любой совет по этому вопросу будет очень признателен. Спасибо, Киран

Ответы [ 3 ]

0 голосов
/ 06 декабря 2011

Есть много-много способов облысения кошки:

  1. Вы ищете унифицированные инициализаторы C ++ 0x:

    std::vector<type> v { x, y };
    
  2. Или просто старый C ++ 03:

    type arr[] = { x,y };
    std::vector<type> v(arr, arr+2);
    
  3. Если вам нужен класс со структурно-подобным поведением, используйте кортеж:

    std::tuple<type, type> point(x,y);
    

    Кортежи в TR1, C ++ 0x и в Boost.У них есть все виды отличных функций (например, автоматическое взаимодействие с std :: pair, std :: less и т. Д.)


В отсутствие всего вышеперечисленного, следующиебудет идиоматическим:

typedef std::pair<type, type> point_t;

point_t p(x,y);
0 голосов
/ 20 апреля 2012

Если вы имеете дело с двумерными векторами и хотите использовать uBLAS, тогда было бы разумно ввести некоторые вспомогательные функции. Кстати, когда вы работаете с векторами фиксированного размера, более эффективно использовать bounded_array хранилище (в стеке)

Я подумал о следующих решениях (ни одно из них не является идеальным, было бы неплохо иметь uBlas совместимым с std::initialization_list):

// Assignment:
#include <boost/numeric/ublas/assignment.hpp>
ublas::bounded_vector<double,2> v1;
v1 <<= 1.1, 2.1; // syntactic sugar over plain assignment

// Use a helper
template<typename T>
ublas::vector<T> makeVector2(T x1, T x2) 
{
    ublas::bounded_vector<T,2> res; // I
    res <<= x1, x2; // or plain res(0)=x1; res(1)=x2;
    return res;
}
ublas::vector<double> v1 = makeVector2<double>(1,2.2);

// Use an `evil' conversion-helper (or it's templatized variant)
class Foo {
public:
    Foo(double x1, double x2) : m_x1(x1), m_x2(x2) {}
    operator ublas::vector<double>() { return makeVector2(m_x1, m_x2); };
private:
    double m_x1, m_x2;
};
ublas::vector<double> v3(Foo(1.3,2.3));

Наконец взглянем на Пример 3 .

0 голосов
/ 06 декабря 2011

2D как в многомерном массиве или две координаты?Если многомерный, используйте вектор векторов:

vector<vector<type>> v;

В этом случае я не уверен, что вы подразумеваете под x и y.И используйте оператор [] вместо оператора (): v[1] = x и т. Д.

Если бы две координаты (ось x, ось y), я сделал бы что-то вроде этого:

template <class T>
class Vector2
{
public:
    Vector2(const T& x, const T& y) : mX(x), mY(y) {}

private:
    T x;
    T y;
};

Причина, по которой я склонен создавать собственный класс Vector2, а не использовать существующий std :: vector, заключается в том, что вы избавляетесь от тонны накладных расходов, которые вы бы не использовали, если все, что вы храните, - это два значения.Это включает в себя динамическое выделение памяти, сохранение длины массива и т. Д. Вам не нужно все это, если все, что вы делаете - это сохранение двух значений.

...