How should I handle the following situation :
I am writing my own 2D vector class and have the following code:
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());
}
// ...
};
Now if I say Vector2 v(3.0f, 4.0f);
it compiles fine and calls the appropriate float constructor.
But if I write Vector2 v(3, 4);
it fails because the templated iterator constructor "fits better" and Vector2(Iterator(3), Iterator(4))
is called.
What should I do in this case?
My idea was about introducing assign(It1, It2)
member method instead of the constructor but maybe there is a better solution?
Also, what do you think about ASSERT(end - begin == 2)
line? I know that this means I can't, for example, pass iterators of std::list
, but brings additional safety. Should I do this or not?
Something like this seems to work:
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)
{
}
};
I believe it's using SFINAE to prevent the compiler selecting the second ctor for non-numeric types.
As for ASSERT (end - begin == 2)
, I think you should be using std::distance(begin, end)
to determine the distance between two iterators.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With