【问题标题】:Changing the constructor of a boost vector更改 boost 向量的构造函数
【发布时间】:2011-12-05 20:55:21
【问题描述】:

我正在尝试更改 BOOST uBLAS 向量的构造函数行为,并且想知道最好的方法是什么。我想使用构造函数初始化二维向量的分量(坐标),例如:

代替:

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);

我想我可以创建一个新类,通过包含或继承自 boost 向量类来提供一个接口来执行此操作,但我对 C++ 相当陌生,我不确定最好的方法保留升压向量的功能。特别是因为我不想干扰 uBLAS 矢量类使用的模板表达式优化。对此的任何建议将不胜感激。 谢谢, 基兰

【问题讨论】:

    标签: c++ boost constructor ublas


    【解决方案1】:

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

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

    【讨论】:

    • 感谢您的回复。我的意思是 2D 有两个坐标。我已经创建了一个与您类似的 Vector2 类,其中包含大量数学运算方法(点积等)。但是,由于从外观上创建了临时对象,因此发现将许多这些操作串在一起时效率非常低。这就是我尝试切换到使用 BOOST uBLAS 向量的原因。我遇到的问题是 uBLAS 向量中没有像您建议的那样内置构造函数; Vector2(const T&amp; x, const T&amp; y) : mX(x), mY(y) {}
    【解决方案2】:

    有很多种给猫剥皮的方法:

    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);
    

    【讨论】:

      【解决方案3】:

      如果您经常处理二维向量并想使用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));
      

      终于来看看Example 3。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-06-11
        • 1970-01-01
        • 2017-06-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多