Вопрос по типизации - страница 2

 
Ilya Malev:

Ну Вы другими словами повторили то, что я и написал. Вопрос был не в том, может или не может, а почему не может и как это изящно обойти

написать просто функции для конверсий и не мучать switch внутри методов ?

double Double(CParameter<double>)

string String(CParameter<double>)

и использовать :

PrintFormat("%s %s %f",String(param1),String(param2),Double(param1));

да и какая разница, использовать унарный оператор или именованную функцию ? функцию лучше - у оператора уже есть смысловая нагрузка и произвольно её менять не айс

 
fxsaber:

Контроль типов теряется. Посмотрите C++-ресурсы на предмет ответа на эти вопросы. Думаю, они задаются довольно часто.

Ну хотя бы разобрался с тем, что это не ограничение mql, а особенность С++ в целом, и на том спасибо :)

 
А невозможность перегрузки операторов без привязки lparam перегруженного оператора к конкретному объекту или структуре, это тоже особенность С++?
 
Ilya Malev:

С явной перегрузкой и ариф.действиями и так все понятно. Да, перегруженный = явно удачнее в этом случае, Вы правильно заметили, просто я на скорую руку сооружал пример для вопроса и не особенно о нем задумывался (хотя там number не только int, a ещё char, uchar, short, ushort, uint, bool и color, так что не все однозначно )))))))


Тут вопрос в том, чтобы тип возвращаемого значения перегруженного метода зависел от содержания объекта.

Например, имеем разнотиповый массив (примеры приводить не буду, т.к. многобуков). И, разумеется, в любом массиве должна быть операция [] индексации, возвращающая значение переменной с соответствующим индексом.

Но переменные имеют разные типы. Там может быть datetime, а может быть string, или вообще какой-нибудь пользовательский тип под этим индексом. И хотелось бы в идеале, чтобы тип возвращаемого значения при индексации [] автоматически выдавал соответствующий тип, без необходимости его явно параметризовывать. Раньше я эту "проблему" решал так: var[(char)1], var[(short)1], var[(uint)1] и т.п. но эти костыли никуда не годятся.

Использовать массив структур типа mqlparam.

 
Dmitry Fedoseev:

Массив структур типа mqlparam.

Его точно так же не приравняешь к double, string или long

MqlParam par;

par.double_value = Ask;

double d = par; // '=' - illegal operation use

 
Ilya Malev:

Его точно так же не приравняешь к double, string или long

MqlParam par;

par.double_value = Ask;

double d = par; // '=' - illegal operation use

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

 
Ilya Malev:
А невозможность перегрузки операторов без привязки перегруженного оператора к конкретному объекту или структуре, это тоже особенность С++?

Вот что пишут в интернете про это:

Перегрузка функций невозможна, если они различаются только лишь типами возвращаемого значения.

Стандарт C++14 13.1/2:

 

Нашел такое в сети в ответах на схожий вопрос:

template<typename T> T f();
template<> int f() { return 2; }
template<> double f() { return 2.7; }

//...
struct F {
    F() {}
    template<typename T> operator T() { return f<T>(); }
};

int x2 = F();
double y2 = F();


Как я понял, тут перегружается оператор приведения к типу "operator T()" - значит в С++ такое как минимум возможно. А в mql как я понимаю пока нет.

 
Ilya Malev:
схожий вопрос: почему при перегрузке метода (в сигнатуре перегруженного метода) не фигурирует тип возврата, а фигурируют только типы параметров. то есть нельзя определить два идентичных метода с разными типами возвращаемого значения. почему сделано такое ограничение? какой в этом смысл, почему нельзя сделать перегрузку метода по типу возвращаемого значения при идентичных параметрах

Наверное поэтому:

int f() {
   call_something();
   return 0;
}

double f() {
   call_something_other();
   return 0;
}

void start() {
   f();
}

Какая именно функция должна вызываться?

 
pavlick_:

Наверное поэтому:

Какая именно функция должна вызываться?

Наверное должно на этапе компиляции выдаваться ошибка template mismatch.


А вот в ситуации, когда есть объект array

class Array{

public:

Array *operator[] (int i){ id = i; return GetPointer( this ); }

double operator[]( int i){ id = i; return data[i]; }

Array *operator=(double d){ data[id]=d; return GetPointer( this ); }

private:

double data[10];

int id;

};



int OnStart(){

  Array array;

  double d=123.456;

  array[5]=d;

  d=array[5];

}

Такой ошибки уже возникать не должно, потому что в первом случае вызов Array[int] используется как левый параметр операции =, и не является переменной double, а во втором случае как правый, причем левый параметр является переменной типа double.

То есть в итоге тема сводится к пожеланию ввести в mql возможность перегрузки операции типизации (в т.ч. неявной), то есть определения контекста вызова метода и в зависимости от ожидаемого в данном контексте типа возвращаемого значения вызывать нужный код. А если контекст явно не определяем, то выдавать ошибку.

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