J'essaie std :: enable_if pour la première fois et j'ai du mal à le faire. Toute recommandation serait appréciée.enable_if avec les constructeurs de copie
Comme exemple de jouet, voici une classe simple vecteur statique, pour lequel je veux définir un constructeur de copie, mais le comportement dépend de la taille relative des vecteurs:
- copier uniquement les données dans un plus ou moins de même taille vecteur
- copier les données dans un vecteur plus grand, puis pad le reste avec des zéros
Ainsi la classe vecteur est:
template <size_t _Size>
class Vector
{
double _data[_Size];
public:
Vector()
{
std::fill(_data, _data + _Size, 0.0);
}
const double* data() const
{
return _data;
}
...
};
Le constructeur de copie devrait soutenir quelque chose comme cela, la copie des 2 premiers éléments de v3 en v2:
Vector<3> v3;
Vector<2> v2(v3);
J'ai essayé un constructeur de copie pour le comportement 1. comme celui-ci, qui compile:
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);
}
mais le compilateur ne peut pas le distinguer du comportement 2. même si les conditions enable_if s'excluent mutuellement.
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);
}
J'ai aussi essayé de mettre enable_if dans l'argument à la place, mais il ne pouvait pas en déduire la valeur de _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);
}
Quelle est la meilleure façon de le faire (en utilisant enable_if, et non d'un simple si déclaration)?
Merci
Un constructeur de copie ne peut pas être un modèle, par définition. Vous pouvez avoir un constructeur basé sur un modèle qui le copie, mais il ne sera toujours pas un constructeur de copie. ;]] – ildjarn
Ce n'est pas le problème, mais les noms qui commencent par un trait de soulignement suivi d'une lettre majuscule ('_Size',' _OtherSize') et les noms qui contiennent deux traits de soulignement consécutifs sont réservés à l'implémentation. Ne les utilisez pas dans votre code. –
Indépendant mais vous n'avez pas besoin de 'typename' avant' std :: enable_if_t'. – Oktalist