Error al usar using

 

Hola,

Con la última versión build 5260 de MT5, un código que compilaba correctamente en versiones anteriores ahora ya no compila debido a los nuevos cambios en las reglas de ocultación de funciones.

El código de ejemplo es el siguiente:

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class A
 {
protected:
  int                arr[];

public:
  void               Init();
  int                operator[](const int index) { return arr[index]; }
 };
//+------------------------------------------------------------------+
void A::Init()
 {
  ArrayResize(arr, 10);
  MathSrand(GetTickCount());
  for(int i = 0; i < 10; i++)
   {
    arr[i] = MathRand();
   }
 }


//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class B : public A
 {
public:
  using A::operator[];
  int                operator[](const string name) { return name == "Hello" ? arr[0] : arr[2]; }
 };


//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
enum ENUM_TYPE_SELECT
 {
  SELECT_0 = 0,
  SELECT_1 = 1
 };

//+------------------------------------------------------------------+
class C : public B
 {
public:
  using B::operator[]; //                   
  int                operator[](const ENUM_TYPE_SELECT type) { return arr[type]; }
 };



//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnStart()
 {
  C instance;
  instance.Init();
  const int val = instance[0];
  Print(val);
 }
//+------------------------------------------------------------------+

Obviamente, este código es una recreación simplificada de lo que realmente tengo implementado (en mi caso está adaptado a una lógica de sesiones).

Con esta nueva actualización, el operator[] definido en la clase C oculta a los demás operadores heredados. Para evitar este comportamiento utilicé "using", con el objetivo de "re-exponer" los operadores de las clases base y poder usarlos en la clase C.

Sin embargo, al momento de llamar a instance[0] (que en teoría debería invocar a operator[](const int index)), aparece el siguiente error:

const int val = instance[0]; // function must have a body       mc.mq5  72      27

Por lo que entiendo, el compilador interpreta que el operador no tiene implementación y solo está declarado, cuando en realidad los tres operadores tienen cuerpo definido.

¿A alguien más le ha sucedido esto con la build 5260?
¿Alguna sugerencia para resolverlo?

 
Niquel Mendoza:

Sí, es un bug introducido en la build 5260. El compilador no maneja bien la re-exposición de operator[] mediante using, y por eso devuelve "function must have a body" aunque la implementación exista en la clase base.

Mientras MetaQuotes lo corrige, la única solución es implementar wrappers explícitos en la clase derivada, en vez de using:

class C : public B

  {
public:
   int operator[](const int i)              { return B::operator[](i); }
   int operator[](const string s)           { return B::operator[](s); }
   int operator[](const ENUM_TYPE_SELECT t) { return A::operator[]((int)t); }
  };

De momento no hay reporte público en el foro inglés, así que conviene abrir ticket en la Mesa de Servicio adjuntando este ejemplo.

 
Miguel Angel Vico Alba #:

Sí, es un bug introducido en la build 5260. El compilador no maneja bien la re-exposición de operator[] mediante using, y por eso devuelve "function must have a body" aunque la implementación exista en la clase base.

Mientras MetaQuotes lo corrige, la única solución es implementar wrappers explícitos en la clase derivada, en vez de using:

De momento no hay reporte público en el foro inglés, así que conviene abrir ticket en la Mesa de Servicio adjuntando este ejemplo.

Muchas gracias por la ayuda, Miguel.

De momento aplicare la solución temporal que mencionaste.