2

I'm trying to change the constructor behaviour of a BOOST uBLAS vector and was wondering what the best way to do this is. I want to initialise the components (co-ordinates) of a 2D vector using the constructor, for example:

Instead of:

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

I want to be able to specify x and y in the constructor.

BoostVector<double> v(x,y);

I'm thinking I could create a new class that provides an interface for doing this, either by containing or inheriting from the boost vector class, but I'm fairly new to C++ and I'm not sure of the best way to retain the functionality of the boost vector. Especially as I don't want to interfere with the template expression optimisation used by the uBLAS vector class. Any advice on this would be very appreciated. Thanks, Kieran

4

3 回答 3

0

There are many many ways to skin a cat:

  1. Are you looking for C++0x uniform initializers:

    std::vector<type> v { x, y };
    
  2. Or just plain old C++03:

    type arr[] = { x,y };
    std::vector<type> v(arr, arr+2);
    
  3. If you want a class with struct-like behaviour use a tuple:

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

    Tuples are in TR1, C++0x and in Boost. They have all kinds of nifty features (like automatic interoperability with std::pair, std::less etc.)


In the absense of all of the above, the following would be idiomatic:

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

point_t p(x,y);
于 2011-12-05T21:02:31.593 回答
0

如果您正在处理大量 2D 向量并且想要使用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

于 2012-04-19T22:32:37.303 回答
0

二维是多维数组还是两个坐标?如果是多维的,则使用向量的向量:

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 的原因是因为如果你存储的只是两个值,你将摆脱大量的开销,而这些开销是你不会使用的。这包括动态内存分配、存储数组的长度等。如果您所做的只是存储两个值,则不需要所有这些东西。

于 2011-12-05T21:01:58.117 回答