Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Question concernant la surcharge d'opérateur

1 réponse
Avatar
xavier
Soit la hiérarchie suivante :
// vec.h

template <typename N, std::size_t C, typename Conv = conversion_trait<N> >
class Vec : public boost::array<N, C> {
// ...
};

template <typename N, typename Conv = conversion_trait<N> >
class Vec3 : public Vec<N, 3, Conv> {
public:
// constructeurs
Vec3();
Vec3(N const &, N const &, N const &);
template <typename M>
explicit Vec3(M const &); // [1] (assignation d'une valeur à tous les
éléments)
template <typename M, std::size_t C2, typename Conv2>
explicit Vec3(Vec<M, C2, Conv2> const &); // [2]
// ...
};

// ... definition de Vec4 héritant de Vec<N, 4, Conv>

//eof


si j'écris ensuite :

...
Vec4<int> s(1);
Vec3<double> v(s); // [3]
...

Le constructeur appelé en [3] est le constructeur [1], alors que
j'aimerais que ce soit [2].

Actuellement, les seules solutions que j'ai trouvé sont

1) remplacer [2] par :
Vec3(N const &);

2) Ajouter un constructeur :
template <typename M, typename Conv2>
explicit Vec3(Vec4<M, Conv2> const &);

Mais aucune des deux ne me satisfait. La première me faisant perdre
l'avantage de l'appel à conversion_trait<double>::template <typename M>
convert_from<M>(),
la deuxième m'obligeant à réécrire un peu trop de code à mon goût.

Y-aurait-il un moyen supplémentaire (en ajoutant des opérateur de
casting, par exemple) pour arriver à mes fin ?

1 réponse

Avatar
xavier
J'ai trouvé une autre solution, que je juge satisfaisante, pour mon
problème, en utilisant boost::type_traits :

// vec.h

template <typename N, std::size_t C, typename V> class Vec;

template <bool is_arithmetic>
struct vec_assignation_trait {
template <typename N, std::size_t C, typename V, typename N2>
static void assign(Vec<N, C, V> & d, N2 const & s) {
d.assign(V::convert_from<N2>(s));
}
};

template <>
template <typename N, std::size_t C, typename V, typename N2>
void vec_assignation_trait<false>::assign(Vec<N, C, V> & d, N2 const & s) {
// assume N2 is a Vec<>
V::move_from<N2>(d.c_array(), s.data(),
std::min(C, N2::element_count);
}

template <typename N, std::size_t C, typename V>
class Vec : public boost::array<N, C> {
// ...
public:
template <typename N2>
explicit Vec(N2 const & v) {
vec_assignation_trait<
boost::is_arithmetic<N2>::value >::assign(*this, v);
}
};

//... idem pour Vec3 et Vec4

xavier