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

 

в b3095 запускаю скрипт:

template <typename T>
void f1(T* const Ptr) {Print(__FUNCSIG__);}

template <typename T>
void f1(T* & Ptr) {Print(__FUNCSIG__);}


class X {};

void OnStart()
  {
//---
   const X* Ptr = new X;
   
   f1(Ptr);                               //void f1<const X>(const X*&)
   f1<const X>(Ptr);                      //void f1<const X>(const X*&)
   
   //дальше непонятно!
   f1<const X>((const X*) Ptr);           //void func_902::f1<const X>(const X*const)
   f1<const X>((const X* const) Ptr);     //void func_902::f1<const X>(const X*const)
   f1<const X>((X*)Ptr);                  //void func_902::f1<const X>(const X*const)
 
   delete Ptr;
  }

Если убрать перегрузку f1(T* & Ptr), то все 5 вызовов возвращают void f1<const X>(const X*const).

Это какая-то особенность?

 

Объясните, пожалуйста:

В строке *1* выдается ошибка компилятора - ожидамо.

А строка *2* отлично компилируется и работает. Почему?

int f(int & p) {return p;}

class X
  {
public:
   const int         i;
                     X(){}
        /*1*/      //X(X& x) : i(f(x.i)) {f(x.i);}  //'i' - constant variable cannot be passed as reference
        /*2*/        X(X& x) : i(f(x.i)) {}          //OK
  };

void OnStart()  {}
 
mktr8591 #:

Объясните, пожалуйста:

В строке *1* выдается ошибка компилятора - ожидамо.

А строка *2* отлично компилируется и работает. Почему?

Нужно явное противоречие показать (что Вы значение const поменяли):

int f( int &p ) { return p = !p; }
struct X {
        const int i;
        X( int i ) : i( i )      {}
        X( X& x  ) : i( f(x.i) ) {}
};
void OnStart()
{
        X x1( 1 );
        const int i =  x1.i;
                                { X x2 = x1; }
        Print(    i == x1.i );  //Результат: false - не может быть
}
А Вы предлагаете и опытным Пользователям догадываться и Разработчикам
 
A100 #:

значение const поменяли

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Особенности языка mql5, тонкости и приёмы работы

fxsaber, 2017.11.07 14:57

Можно ли поменять поля const-объекта класса или вызвать его не const-методы? -Можно!
template <typename T>
T GetMe( const T Ptr )
{
  return((T)Ptr);
}

class A
{
public:  
  int i;
};

void OnStart()
{
  const A a;

  GetMe(&a).i = 1;
  
  Print(a.i); // 1
}

Самому не нравится такая фишка. Думал, что застрахован от несанкционированного доступа. Облом, однако! С const-структурами такое, конечно, не прокатывает. Так что имейте в виду эту лазейку.


 
A100 #:

Нужно явное противоречие показать (что Вы значение const поменяли):

А Вы предлагаете и опытным Пользователям догадываться и Разработчикам
так подробно расписать не додумался...
 
fxsaber #:
Да. Но у вас в примере явное ( через ф-ю) преобразование const T в T   -  т.е. "легализованная" лазейка.
 
mktr8591 #:
Да. Но у вас в примере явное ( через ф-ю) преобразование const T в T   -  т.е. "легализованная" лазейка.
((A*)(&a)).i = 1;    
 
fxsaber #:
аналогично - (const A*) конвертируете в A*.
 
mktr8591 #:
аналогично - (const A*) конвертируете в A*.
((A)a).i = 1;
 
fxsaber #:

В Вашем примерe явное преобразование const к non const, а там все чисто

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