C ++基本构造函数问题

时间:2010-07-08 15:27:45

标签: c++ constructor templates vector

我应该如何处理以下情况:

我正在编写自己的2D矢量类,并且具有以下代码:

class Vector2 : public (...)
public:

   Vector2(float x, float y) {

      local_vector_storage_[0] = x;
      local_vector_storage_[1] = y;
   }

   template <typename Iterator> Vector2(Iterator begin, Iterator end) {

      ASSERT(end - begin == 2);

      resize(2);

      std::copy(begin, end, local_vector_storage_.begin());
   }

// ...
};

现在如果我说Vector2 v(3.0f, 4.0f);它编译得很好并调用适当的float构造函数。

但是如果我写Vector2 v(3, 4);它会失败,因为模板化的迭代器构造函数“更适合”并调用Vector2(Iterator(3), Iterator(4))

在这种情况下我该怎么做?

我的想法是关于引入assign(It1, It2)成员方法而不是构造函数,但也许有更好的解决方案?

编辑:

另外,您如何看待ASSERT(end - begin == 2)行?我知道这意味着我不能,例如,传递std::list的迭代器,但带来额外的安全性。我应该这样做吗?

4 个答案:

答案 0 :(得分:6)

这样的事似乎有效:

template<typename T>
struct notnumeric {typedef int OK;};

template<>
struct notnumeric<int> {};

class Vector2
{
public:
   Vector2(float x, float y)
   {
   }

   template <typename Iterator>
   Vector2(Iterator begin, Iterator end, typename notnumeric<Iterator>::OK dummy = 0)
   {
   }
};

我相信它正在使用SFINAE来阻止编译器为非数字类型选择第二个ctor。

至于ASSERT (end - begin == 2),我认为您应该使用std::distance(begin, end)来确定两个迭代器之间的距离。

答案 1 :(得分:1)

编辑:这是一个二维矢量吗?或者只是两个向量?我回答了这个2d向量。

  

我应该如何处理以下情况

我认为您应该通过删除float构造函数来处理它。从阅读代码开始,我们不清楚你应该从中得到什么样的对象。

通过阅读callsite代码,我没有理由相信vector2 v2(1, 5);创建了两个向量的向量,每个向量都有一个值。

就个人而言,我原本希望它能创建一个1x5矩阵。

如果这是您图书馆的常见用例,请考虑使用named constructor

vector2 Create2x1(float f1, float f2);
  

re:ASSERT

ASSERT是一个很好的健全性检查,但需要你的Iterator支持随机访问(或至少减去查找距离)。这可能会过度限制其使用。考虑使用std::distance或检查local_vector_storage之后是否为{2}。

答案 2 :(得分:1)

在特定情况下,我认为根本没有介绍Vector2(Iterator begin, Iterator end) c'tor的感觉。

一般情况下,当std::vector的维度固定且永不改变时,我认为模仿Vector2(实质上是数组的包装)是没有意义的。 std::vectorVector2之间的用例重叠可忽略不计:std::vector通常从另一个容器初始化,而Vector2则为50/50用两个值或另一个Vector2初始化。

即使你决定继续,行:

ASSERT(end - begin == 2);

会极大地限制构造函数的有用性,因为相对较少的迭代器支持算术。

答案 3 :(得分:1)