Баг компилятора при параметре шаблона = void*

 

Ошибка компилятора.  Билд 1961, 64 бит.

template<typename T>
class A
{ 
};

A<void*> a;  // '<' - cannot to apply function
 
А раньше можно было?
 
Вечером проверю как с таким объявлением у С++
 
Vladimir Simakov:
А раньше можно было?

Да.  Специально проверил на старом билде (1554) - всё работает. 

Вечером проверю как с таким объявлением у С++

Ну там уж тем более всё в порядке.  Разве есть какие-то основания, почему это может не работать?
 
Alexey Navoykov:

Приведите, пожалуйста, пример использования этой конструкции.

 
fxsaber:

Приведите, пожалуйста, пример использования этой конструкции.

Самый банальный пример - класс массива.  В данном случае используется для хранения любых указателей:

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:

Самый банальный пример - класс массива.  В данном случае используется для хранения любых указателей.

Как использовать тогда?

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:

Как использовать тогда?

Ну точно также, как используют например CObject в метаквотовских контейнерах.  Кастишь к тому типу, который ты туда засовывал изначально (либо через dynamic_cast проверяешь).  Немного неожиданно слышать от вас такой вопрос.
 
Alexey Navoykov:
Кастишь к тому типу, который ты туда засовывал изначально (либо через dynamic_cast проверяешь).
//    (A*)Pointers[i].OnInit();
    ((A*)Pointers[i]).OnInit();

Это как раз на тему нужности/ненужности скобок... С таким кастингом будет облом в скрипте выше при выполнении. Т.е. нужно знать имена классов, на которые ссылаются элементы-указатели массива.

Тогда не уловил, в чем удобство.


У MQ только в одном месте используется void*.

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

У MQ только в одном месте используется void*.

Потому что у них всё построено на CObject.  И это делает невозможным использование их контейнеров для собственных классов и интерфейсов, не унаследованных от их класса.  Т.е. не универсальное решение.

Возможно это по причине того, что на момент создания их библиотеки в MQL ещё не было void*.  Хотя с другой стороны, у них сам объект тоже участвует в некоторых манипуляциях (меняются значения указателей в нём), что само по себе просто дикость.

 
Alexey Navoykov:

Потому что у них всё построено на CObject.  И это делает невозможным использование их контейнеров для собственных классов и интерфейсов, не унаследованных от их класса.  Т.е. не универсальное решение.

Возможно это по причине того, что на момент создания их библиотеки в MQL ещё не было void*

К сожалению, так и не увидел примера использования.

Причина обращения: