I am trying std::enable_if
for the first time and struggling. Any guidance would be appreciated.
As a toy example, here is a simple static vector
class, for which I want to define a copy constructor, but the behavior depends on the relative sizes of the vectors:
- just copy data into a smaller or same-sized vector
- copy data into a larger vector and then pad the rest with zeroes
So the vector
class is:
template <size_t _Size>
class Vector
{
double _data[_Size];
public:
Vector()
{
std::fill(_data, _data + _Size, 0.0);
}
const double* data() const
{
return _data;
}
// ...
};
The copy constructor should support something like this: copying the first 2 elements of v3
into v2
:
Vector<3> v3;
Vector<2> v2(v3);
I tried a copy constructor for behavior 1. like this, which compiles:
template <size_t _OtherSize,
typename = typename std::enable_if_t<_Size <= _OtherSize>>
Vector(const Vector<_OtherSize>& v) : Vector()
{
std::copy(v.data(), v.data() + _Size, _data);
}
but the compiler cannot distinguish this from behavior 2. even though the enable_if
conditions are mutually exclusive.
template <size_t _OtherSize,
typename = typename std::enable_if_t<_OtherSize < _Size>>
Vector(const Vector<_OtherSize>& v) : Vector()
{
std::copy(v.data(), v.data() + _OtherSize, _data);
std::fill(_data + _OtherSize, _data + _Size, 0.0);
}
I also tried putting enable_if
in the argument instead, but it couldn't deduce the value of _OtherSize
:
template <size_t _OtherSize>
Vector(const typename std::enable_if_t<_Size <= _OtherSize,
Vector<_OtherSize>> & v)
: Vector()
{
std::copy(v.data(), v.data() + _Size, _data);
}
What is the way to do this (using enable_if
, not a simple if
statement)?
_Size
,_OtherSize
) and names that contain two consecutive underscores are reserved for use by the implementation. Don’t use them in your code. – Veligertypename
beforestd::enable_if_t
. – Sortie