Compilerfehler mit Template-Parameter = void*

 

Compilerfehler, Bild 1961, 64 bit.

template<typename T>
class A
{ 
};

A<void*> a;  // '<' - cannot to apply function
 
War das früher möglich?
 
Ich werde diese Ankündigung mit C++ am Abend überprüfen.
 
Vladimir Simakov:
War das früher möglich?

Ja, ich habe es speziell mit dem alten Build (1554) überprüft - alles funktioniert.

Ich werde es heute Abend mit einer solchen Ankündigung in C++ überprüfen.

Gibt es irgendeinen Grund, warum es nicht funktionieren könnte?
 
Alexey Navoykov:

Bitte geben Sie ein Beispiel für die Verwendung dieser Konstruktion.

 
fxsaber:

Bitte geben Sie ein Beispiel für die Verwendung dieses Konstrukts.

Das trivialste Beispiel ist eine Array-Klasse, die in diesem Fall zum Speichern beliebiger Zeiger verwendet wird:

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:

Das trivialste Beispiel ist die Array-Klasse, die in diesem Fall zum Speichern beliebiger Zeiger verwendet wird.

Wie kann man es dann verwenden?

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:

Wie kann man es dann verwenden?

Auf die gleiche Weise, wie z.B. CObject in Metaquote-Containern verwendet wird. Casten Sie auf den Typ, den Sie dort ursprünglich angegeben haben (oder verwenden Sie dynamic_cast, um dies zu überprüfen). Es ist etwas überraschend, dass Sie diese Frage stellen.
 
Alexey Navoykov:
Cast auf den Typ, den Sie dort ursprünglich eingegeben haben (oder mit dynamic_cast überprüfen).
//    (A*)Pointers[i].OnInit();
    ((A*)Pointers[i]).OnInit();

Es geht nur um die Frage, ob Klammern notwendig/unnötig sind... Mit diesem Casting würde es im obigen Skript bei der Ausführung einen Knaller geben. D.h. Sie müssen die Namen der Klassen kennen, auf die sich die Zeigerelemente des Arrays beziehen.

Ich verstehe nicht, was daran so bequem sein soll.


MQ verwendet void* nur an einer Stelle.

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

MQ verwendet void* nur an einer Stelle.

Da sie alles auf CObject aufbauen, ist es unmöglich, ihre Container für ihre eigenen Klassen und Schnittstellen zu verwenden, die nicht von ihrer Klasse geerbt werden, d.h. es ist keine universelle Lösung.

Das liegt wahrscheinlich daran, dass es zum Zeitpunkt der Erstellung ihrer Bibliothek noch kein void* in MQL gab, obwohl sie auf der anderen Seite auch das Objekt selbst haben, das an einigen Manipulationen beteiligt ist (Ändern von Werten von Zeigern darin), was an sich einfach wild ist.

 
Alexey Navoykov:

Dies macht es unmöglich, ihre Container für ihre eigenen Klassen und Schnittstellen, die nicht von ihrer Klasse geerbt wurden, zu verwenden, d.h. es ist keine universelle Lösung.

Vielleicht liegt das daran, dass es zu der Zeit, als die Bibliothek erstellt wurde, noch kein void* in MQL gab.

Leider habe ich noch kein Beispiel für seine Verwendung gesehen.

Grund der Beschwerde: