C++基本构造函数问题

Yip*_*Yay 8 c++ templates constructor 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());
   }

// ...
};
Run Code Online (Sandbox Code Playgroud)

现在,如果我说它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,但带来额外的安全性.我应该这样做吗?

jon*_*son 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)
   {
   }
};
Run Code Online (Sandbox Code Playgroud)

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

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

  • 您可以使用`std :: enable_if <!std :: is_numeric <Iterator> :: value,Iterator> :: type`来改进它.这将删除"dummy"参数并使用编译器提供的(或Boost,如果你是绝望的)类型特征,这比自定义编写的类型特征更可靠.另外,你可以抛出,而不是使用assert. (2认同)