Баг компилятора - ошибка передачи указателей в шаблоны

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
Alexey Navoykov
4569
Alexey Navoykov  

Билд 1966, 64 бит.  Компилятор некорректно воспринимает шаблон, заданный в такой форме:

template<typename T>
void f(T const&) {  }

либо

template<typename T>
void f(T const&[]) {  }

В такие шаблоны невозможно передать указатели, ни в каком виде:

template<typename T>
void f(T const&) {  }


class A {  };


void OnInit()
{
  A *a;
  f(a);            // 'f' - cannot to apply function template
  
  const A *b;
  f(b);  /          // 'f' - cannot to apply function template

  A const *b2;
  f(b2);             // 'f' - cannot to apply function template
  
  A *const c = NULL; 
  f(c);               // 'f' - cannot to apply function template
  
  A const*const d =NULL;  
  f(d);                // 'f' - cannot to apply function template

  const A*const d2 = NULL; 
  f(d2);               // 'f' - cannot to apply function template
}

А в некоторых из этих случаев возникает ещё и ошибка  'const' - unexpected token  в самом шаблоне.


Хотя этот шаблон равносилен:

template<typename T>
void f(const T&) {  }

В таком написании всё компилируется. НО!  Тогда возникает другая ошибка:

class A {  };

void f(A*const&) {  } 

template<typename T>
void g(const T &a)
{ 
  f(a); // 'a' - cannot convert from const pointer to nonconst pointer
}  

void OnInit()
{
  A* a;
  g(a);
}

Т.е. при попадании в такой шаблон указатель меняет тип - становится константным указателем.  Хотя const в шаблоне относится лишь к константности переменной.

fxsaber
16702
fxsaber  
Согласен.
Alexey Navoykov
4569
Alexey Navoykov  

В общем из-за этих багов не получается реализовать такую конструкцию

template<typename T>
interface ISome {  };

template<typename T>
void f(T const& arr[], ISome<T>&) {  }

чтобы f могла принимать любые типы, включая указатели.

Если сделать перегрузку шаблона для указателей:

template<typename T>
void f(T* const& arr[], ISome<T*>&) {  }

то это не работает, компилятор выдаёт ошибку при попытке передачи массива указателей.  Он вообще не понимает такую конструкцию шаблонного аргмента: ISome<T*>&  - ранее об этом баге я тоже сообщал.

Печально, что из-за багов в MQL до сих пор невозможна полноценная работа с шаблонами.

pavlick_
773
pavlick_  
А в чём необходимость использовать interface, почему нельзя обойтись абстрактным классом? Зачем его вообще ввели?
Alexey Navoykov
4569
Alexey Navoykov  
pavlick_:
А в чём необходимость использовать interface, почему нельзя обойтись абстрактным классом? Зачем его вообще ввели?
Да хоть класс, хоть интерфейс, на баги это не влияет.
pavlick_
773
pavlick_  
Alexey Navoykov:
Да хоть класс, хоть интерфейс, на баги это не влияет.

Ну так то да. Просто интересно - ведь должна же быть какая-то последовательность в действиях, назвались плюсовым аналогом, зачем тогда интерфейсы пихать? Какую проблему они решают да так красиво, что абстрактные классы курят в сторонке? А то можно и от лиспа, например, чего-нибудь впаять:

(setq-default indent-tabs-mode nil)
(global-set-key (kbd "<up>") (lambda () (interactive) (scroll-down-command 1)))
(global-set-key (kbd "<down>") (lambda () (interactive) (scroll-up-command 1)))

"Родила царица в ночь не то сына, не то дочь ..."

Просто я был немного в шоке после просмотра https://www.mql5.com/ru/docs/standardlibrary/generic/icollection. Так использовать и не стал.

Документация по MQL5: Стандартная библиотека / Шаблонные коллекции данных / ICollection
Документация по MQL5: Стандартная библиотека / Шаблонные коллекции данных / ICollection
  • www.mql5.com
Интерфейс ICollection определяет основные методы для работы с коллекциями: подсчет количества элементов, очистку коллекции, добавление и удаление элементов и другие.
TheXpert
18270
TheXpert  
pavlick_:

зачем тогда интерфейсы пихать?

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

но еще не доделали.

pavlick_
773
pavlick_  
Ясно, спасибо.
Alexey Navoykov
4569
Alexey Navoykov  

Продолжаем тему багов:

template<typename T> void f(T&) { }  // '*' - pointer cannot be used
template<typename T> void f(T*&) { }

void OnInit()
{ 
  int b;
  f<int>(b); // 'f<int>' - ambiguous call to overloaded function with the same parameters
}

А без явной типизации работает нормально.

Там вообще чудеса всякие творятся при явной типизации.

fxsaber
16702
fxsaber  
Alexey Navoykov:

Продолжаем тему багов:

А без явной типизации работает нормально.

Там вообще чудеса всякие творятся при явной типизации.

Ну это древний баг почившего Сервисдеска.

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий