Bonjour à tous

Est-il possible de tester la présence d'une fonction ou d'un typedef dans un paramètre template et de compiler un code spécifique en conséquence ?

Pour préciser ce que je recherche :
Imaginons un conteneur 2D, utilisant en interne un conteneur définit dans un paramètre template (par exemple un std::vector ou un QVarLengthArray). QVarLengthArray ne fournit pas de typedef iterator ou de fonction begin(). J'aimerai donc que ma classe utilise le typedef iterator du conteneur s'il existe ou un code spécifique sinon. Ça ressemblerait à ça :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
template<typename T, template <typename T> class CONT = std::vector>
class Array2D
{
private:
   CONT<T> elems;
 
public:
 
#ifdef (CONT::iterator)
   typedef typename CONT::iterator iterator;
   iterator  begin() { return elems.begin(); }
#elseif
   typedef T* iterator;
   iterator  begin() { return &elems[0]; }
#endif
};
J'ai regardé du côté de boost::mpl mais j'ai rien vu d'intéressant (pour ce problème)

C'est juste une question théorique, pour le moment, la solution adopté est "utiliser un conteneur valide et c'est tout"

Merci à vous


EDIT : pour le moment, je vois une solution en utilisant un classe template intermédiaire qui ajouterait ces fonctions manquantes. Ça serait alors de la responsabilité de l'utilisateur de penser à utiliser cette classe intermédiaire.


Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 
template<typename T, template <typename T> class CONT = QVarLengthArray>
class WrapperToArray2D
{
public:
   typedef T* iterator;
   iterator  begin() { return &elems[0]; }
};
 
template<typename T, template <typename T> class CONT = std::vector>
class Array2D
{
private:
   CONT<T> elems;
 
public:
   typedef typename CONT::iterator iterator;
   iterator  begin() { return elems.begin(); }
};
 
Array2D<int, std::vector> array1; //ok
Array2D<int, QVarLengthArray> array2; //erreur
Array2D<int, WrapperToArray2D<int, QVarLengthArray> > array3; //ok
Si quelqu'un voit une meilleure idée