Ошибки, баги, вопросы - страница 1962

 

Ошибка при компиляции

typedef void (*fn)( int );
struct A {
                void f() { return   ; } //(*)
        static  void f( int ) {}
};
void g( fn ) {}
void OnStart()
{
        g( A::f ); //error: 'f' - cannot resolve function address
}

а если заменить строку (*) на

                int  f() { return 0; } //(*)
то нормально. А какая разница?

Похоже на https://www.mql5.com/ru/forum/1111/page1977#comment_5595772, но отличается кодом ошибки  


Ошибки, баги, вопросы
Ошибки, баги, вопросы
  • 2017.08.11
  • www.mql5.com
Форум алго-трейдеров MQL5
 

Ошибка при компиляции

template<typename T>
void g( T ) {}
void f() {}
void OnStart()
{
        g( f ); //error: 'g' - cannot to apply function template
}

а так:


template<typename T>
void g( T ) {}
void f() {}
typedef void (*fn)();
void OnStart()
{
        fn ff = f;
        g( ff ); //нормально
}

нормально. А какая разница?
 
A100:

Ошибка при компиляции

а так:

нормально. А какая разница?

Разница огромная. Когда вызывается g(f), то компилятор понятия не имеет, какого типа f, т.к. прописан только template. Если перегрузить template, то не будет проблем

typedef void (*fn)();

template<typename T>
void g( T Value ) { Print(typename(Value)); }
void f() {}

void g( fn Value ) { Print(typename(Value)); }
void OnStart()
{
        g( f ); // void(*fn)()
}
 
fxsaber:
Время компиляции в 1643

Время компиляции в 1648


Что-то круто подкрутили!

У меня как было, так и осталось, компиляция не ускорилась

 
Vitaly Muzichenko:

У меня как было, так и осталось, компиляция не ускорилась

Возможно, не используете то, что раньше тормозило в TesterBenchmark.mqh

 
fxsaber:

Разница огромная. Когда вызывается g(f), то компилятор понятия не имеет, какого типа f, т.к. прописан только template. Если перегрузить template, то не будет проблем

Если разница огромная, то почему тогда в С++ нормально компилируются оба варианта?
 
A100:
Если разница огромная, то почему тогда в С++ нормально компилируются оба варианта?

Вот не авторитет совсем C++  в данном случае, т.к. основывал заключения на логике. Выше переделал пример с распринтовкой.

Стоит всего лишь сделать такую замену

// typedef void (*fn)();
typedef void (*fn123)();

Как распринтовываться будет совсем другое. Можно попросить, чтобы компилятор был "умнее дурака" и действовал, как в C++. Но это спорное решение на самом деле.

Т.е. такую "помощь" можно осуществить в компиляторе, но разницу в подходах показал.

 
A100:
нормально. А какая разница?

видимо при простой передаче для компилятора f не воспринимается как указатель на функцию.

 
Комбинатор:

видимо при простой передаче для компилятора f не воспринимается как указатель на функцию.

Согласен (все просто и по сути нет никакой разницы)
 
Комбинатор:

видимо при простой передаче для компилятора f не воспринимается как указатель на функцию.

И не должен, хотя бы из-за неоднозначности

typedef void (*fn)();

template<typename T>
void g( T Value ) { Print(typename(Value)); }
void f() {}

void g( fn Value ) { Print(typename(Value)); }
void OnStart()
{
  g( f ); // void(*fn)()

  int f = 0;  
  g( f ); // int
}