Bogue de compilation avec le paramètre template = void*

 

Erreur de compilation. Bild 1961, 64 bits.

template<typename T>
class A
{ 
};

A<void*> a;  // '<' - cannot to apply function
 
Était-ce possible avant ?
 
Je vérifierai cette annonce avec C++ dans la soirée.
 
Vladimir Simakov:
Était-ce possible avant ?

Oui. Je l'ai vérifié spécialement sur l'ancien build (1554) - tout fonctionne.

Je le vérifierai ce soir avec une telle annonce en C++.

Eh bien, c'est certainement OK là. Y a-t-il une raison pour que ça ne fonctionne pas ?
 
Alexey Navoykov:

Veuillez donner un exemple de l'utilisation de cette construction.

 
fxsaber:

Veuillez donner un exemple de l'utilisation de cette construction.

L'exemple le plus trivial est celui d'une classe de tableau, qui sert dans ce cas à stocker des pointeurs :

template<typename T>
class CArray
{
  T _data[]; 
 public:
  T operator[](int i) const { return _data[i]; }
  int Size()          const { return ArraySize(_data); }
  // и т.д.
};

СArray<void*> pointers;
 
Alexey Navoykov:

L'exemple le plus trivial est la classe array, qui sert à stocker des pointeurs.

Comment l'utiliser alors ?

class A
{
public:
  void OnInit()
  {
    Print(__FUNCSIG__);
  }
};

class B
{
public:
  void OnInit()
  {
    Print(__FUNCSIG__);
  }
};

void OnStart()
{    
  void* Pointers[2];

  A a;
  B b;
  
  Pointers[0] = &a;
  Pointers[1] = &b;
  
  for (int i = 0; i < ArraySize(Pointers); i++)
    Pointers[i].OnInit(); // 'OnInit' - member function not defined
}
 
fxsaber:

Comment l'utiliser alors ?

De la même manière que CObject, par exemple, est utilisé dans les conteneurs de métacitations. Le type que vous avez mis en place initialement (ou utilisez dynamic_cast pour vérifier). C'est un peu surprenant de vous entendre poser cette question.
 
Alexey Navoykov:
Le type est celui que vous avez mis à l'origine (ou vérifié via dynamic_cast).
//    (A*)Pointers[i].OnInit();
    ((A*)Pointers[i]).OnInit();

C'est juste sur le sujet de savoir si les crochets sont nécessaires/non nécessaires... Avec ce moulage, le script ci-dessus ne serait pas exécuté correctement. C'est-à-dire que vous devez connaître les noms des classes auxquelles les éléments du pointeur de tableau font référence.

Je ne vois pas ce qui est pratique alors.


MQ n'utilise void* qu'à un seul endroit.

typedef string(*DoubleToStringFunction)(double,void*);
 
fxsaber:

MQ n'utilise void* qu'à un seul endroit.

Comme tout est construit sur CObject, il est impossible d'utiliser leurs conteneurs pour leurs propres classes et interfaces, non héritées de leur classe. Ce n'est donc pas une solution universelle.

Cela est probablement dû au fait qu'au moment de la création de leur bibliothèque, il n'y avait pas encore de void* dans MQL. Mais d'un autre côté, leur objet lui-même prend part à certaines manipulations (changement des valeurs des pointeurs dans l'objet), ce qui en soi est tout simplement délirant.

 
Alexey Navoykov:

Cela rend impossible l'utilisation de leurs conteneurs pour leurs propres classes et interfaces non héritées de leur classe, c'est-à-dire que ce n'est pas une solution universelle.

Peut-être est-ce dû au fait qu'au moment où leur bibliothèque a été créée, il n'y avait pas encore de void* dans MQL.

Malheureusement, je n'ai pas vu d'exemple de son utilisation.