Здравствуйте, Шахтер, Вы писали:
Ш>Понятно, что в этих случаях разрешение перегрузки по типу возвращаемого значения невозможно,
+1
Ш> но тогда какая от неё польза? По-видимому -- минимальная.
Чесно говоря хотелось бы поиметь ее в более простых случаях.
Например мне не очень нравятся конструкции вроде:
TypeOfResult result = (TypeOfResult)Query("некоторый запрос");
Было бы здорово если можно было перегрузить Query по возвращаемому значению. Тогда в него можно было встроить понятное объяснение произошедшей ошибки или еще чего. Ну, и синтаксис стал бы проще.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Павел Кузнецов, Вы писали:
>> Уже давно существует перегрузка методов класса по количеству и типу параметров, но почему нельзя делать перегрузку по типу возращаемого значения?
ПК>Можно. Давно есть в Ada. При желании можно эмулировать в C++ с помощью возвращения прокси-объекта с операциями приведения к соответствующим типам. Как с этим обстоит в C# —
С++ без всяких проксей
class BaseResult {...};
class DerivedResult : public BaseResult {...};
class BaseFactory
{
public:
virtual BaseResult* foo() {...}
};
class DerivedFactory : public BaseFactory
{
public:
virtual DerivedResult* foo() {...}
};
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>VladD2,
>> ПК> Влад, это реализуется не сложнее, чем в C++ выбор из перегруженных функций по типу, стоящему в левой части:
>> Это сложно реализовать в рамках выбранной граматики языка. Конфликты граматики и неопределенности тоже сложности.
ПК>Никаких сложностей в рамках выбранной грамматики тоже нет. Вот пример, наглядно это демонстрирующий: ПК>
ПК>struct C
ПК>{
ПК> C( int );
ПК> operator int() const;
ПК> operator double() const;
ПК>};
ПК>int main()
ПК>{
ПК> int i = C(10);
ПК> double d = C(5);
ПК>}
ПК>
ПК>С точки зрения грамматики выделенные строки эквивалентны случаю, если бы C были бы перегруженными по результату функциями.
Я бы сказал, разрешение перегрузки выполняется после синтаксического анализа, так что грамматика тут совершенно не при чем. Всё что нужно -- чуть-чуть модифицировать блок, выбирающий среди списка перегруженных функций наиболее подходящую. Тут, правда, возникает одна проблема.
Для случая
int a=...;
double b=...;
int x=fun(a,b);
мы точно знаем желательный тип возвращаемого значения.
А вот как быть с таким примером?
int g(int);
int g(double);
int fun(int a,double b);
double fun(int a,double b);
...
int x=g(fun(a,b));
Или ещё лучше.
template <class T>
int g(T);
int fun(int a,double b);
double fun(int a,double b);
...
int x=g(fun(a,b));
Понятно, что в этих случаях разрешение перегрузки по типу возвращаемого значения невозможно, но тогда какая от неё польза? По-видимому -- минимальная.
Здравствуйте, folk, Вы писали:
F>Если я правильно понял, на самом деле тебе хочется не перегрузки по типу возвращаемого значения, а возвращения ковариантного (covariant) типа. F>В С++ это реализовано. Фича удобная, в плюсах проблем не создает (кроме переносимости — не поддерживается древними компиляторами).
Здравствуйте, VladD2, Вы писали:
VD>А какова по-твоему разница между перегрузкой и переопределением?
Ну, у меня возникло подозрение, что LIS спросил про переопределение с возвращением ковариантного типа.
Если же именно про перегрузку — то тем более нет проблем (в С++).
LIS,
> Уже давно существует перегрузка методов класса по количеству и типу параметров, но почему нельзя делать перегрузку по типу возращаемого значения?
Можно. Давно есть в Ada. При желании можно эмулировать в C++ с помощью возвращения прокси-объекта с операциями приведения к соответствующим типам. Как с этим обстоит в C# —
Posted via RSDN NNTP Server 1.9 delta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте, LIS, Вы писали:
LIS>Возможно, я чего-то недопонимаю и этого можно добиться другими методами — советы принимаются с благодарностью
конечно недопонимаешь. есть приведение типов, которое конфликтует с тем что ты хочешь (в теории а не твоем примере). а для твоего случая нужно выходной параметр передавать последним в вызовах метода (а сам метод возвращает значение из списка стандартных) — соответсвенно сможешь перегрузить все как тебе удобно
это паралельная идеология (которая в коме кстати применяется) — методы возвращают значения из определенного списка, а под реальный результат используется последний параметр метода
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>Влад, это реализуется не сложнее, чем в C++ выбор из перегруженных функций по типу, стоящему в левой части:
Это сложно реализовать в рамках выбранной граматики языка. Конфликты граматики и неопределенности тоже сложности.
Авторы языков не решают нужно или нет. Они понимают, что нужно. Просто сравнивая бенефит с проблемами принимают выбор в пользу меньших проблем.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
LIS:
> Уже давно существует перегрузка методов класса по количеству и типу параметров, но почему нельзя делать перегрузку по типу возращаемого значения? Это сложно реализовать или просто не надо никому? Или это может создать проблемы? > > Зачем мне это понадобилось? Приведу такой пример:
[]
Если я правильно понял, на самом деле тебе хочется не перегрузки по типу возвращаемого значения, а возвращения ковариантного (covariant) типа.
В С++ это реализовано. Фича удобная, в плюсах проблем не создает (кроме переносимости — не поддерживается древними компиляторами).
Здравствуйте, Кодт, Вы писали:
К>Если же именно про перегрузку — то тем более нет проблем (в С++).
Речь именно о прегрузке, причем о перегрузке по типу возвращаемого значения. И тут проблемы не у С++, а у дизайнеров языка. Так как с возникающими неоднозначностями приходится бороться.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Давно мучался таким вопросом и вот недавно опять приперло:
Уже давно существует перегрузка методов класса по количеству и типу параметров, но почему нельзя делать перегрузку по типу возращаемого значения? Это сложно реализовать или просто не надо никому? Или это может создать проблемы?
Зачем мне это понадобилось? Приведу такой пример:
// Класс возращаемого значения для BaseClassclass BaseRetVal
{
int Val1 { get {...} set {...}}
}
// Класс возращаемого значения для ChildClass
// Расширяет функциональность BaseRetVal для ChildClassclass ChildRetVal: BaseRetVal
{
int Val2 { get {...} set {...}}
}
class BaseClass
{
private BaseRetVal _m_val;
public virtual BaseRetVal SomeFunc()
{
...
return _m_val;
}
}
// Расширяет функциональность BaseClassclass ChildClass: BaseClass
{
private ChildRetVal _m_val;
public override ChildRetVal SomeFunc()
{
...
return _m_val;
}
}
Хочеться, что бы при вызове ChildClass.SomeFunc возращался тип ChildRetVal.
Возможно, я чего-то недопонимаю и этого можно добиться другими методами — советы принимаются с благодарностью
Я так и думал что такое спросят
В таком случае спросить у программиста что именно он хочет (я имею в виду компилятор)
Немного уточню: возможно ли такая перегрузка для иерархии классов, т.е. :
// Класс возращаемого значения для BaseClassclass BaseRetVal
{
int Val1 { get {...} set {...}}
}
// Класс возращаемого значения для ChildClass
// Расширяет функциональность BaseRetVal для ChildClassclass ChildRetVal: BaseRetVal
{
int Val2 { get {...} set {...}}
}
class BaseClass
{
private BaseRetVal _m_val;
public virtual BaseRetVal SomeFunc()
{
...
return _m_val;
}
public virtual void Process(BaseRetVal val)
{
...
}
}
// Расширяет функциональность BaseClassclass ChildClass: BaseClass
{
private ChildRetVal _m_val;
public override ChildRetVal SomeFunc()
{
...
return _m_val;
}
public override void Process(ChildRetVal val)
{
...
}
...
ChildClass tmp = new ChildClass();
tmp.Process(tmp.SomeFunc());
// вместо tmp.Process((ChildRetVal)tmp.SomeFunc());
// а при попытке выполнить tmp.Process(new BaseRetVal) выдавалось бы предупреждение (или ошибка)
}
Здравствуйте, IPv6, Вы писали:
IP>Здравствуйте, LIS, Вы писали:
LIS>>Возможно, я чего-то недопонимаю и этого можно добиться другими методами — советы принимаются с благодарностью IP>конечно недопонимаешь. есть приведение типов, которое конфликтует с тем что ты хочешь (в теории а не твоем примере). а для твоего случая нужно выходной параметр передавать последним в вызовах метода (а сам метод возвращает значение из списка стандартных) — соответсвенно сможешь перегрузить все как тебе удобно IP>это паралельная идеология (которая в коме кстати применяется) — методы возвращают значения из определенного списка, а под реальный результат используется последний параметр метода
А можно просвятить в чем мой пример конфликтует с теорией приведения типов?
Вот здесь
я уточнил что именно я имею в виду.
Если я могу передать в функцию, принимающую параметр типа BaseClassPar параметр типа ChildOfBaseClassPar без лишних движений, то почему я также не могу и возвращать параметры? Ведь с ChildOfBaseClassPar можно делать все, что можно делать с BaseClassPar!
Про передачу выходного параметра я тоже думал — это вариант (возможно так и сделаю), но хотелось бы элегантнее
Здравствуйте, LIS, Вы писали:
LIS>Уже давно существует перегрузка методов класса по количеству и типу параметров, но почему нельзя делать перегрузку по типу возращаемого значения? Это сложно реализовать или просто не надо никому? Или это может создать проблемы?
AFAIR доктор Страуструп в соответствующей главе "Бибилии Партии" очень подробно и понятно отвечает на Ваш вопрос.
[ posted via RSDN@Home 1.1.4 beta 3 r241, accompanied by Metallica — Master Of Puppets ]
Платформа (.NET) поддерживает перегрузку по возвращаемому значению. Проблема в том что в синтаксисе большинства языков возможны ситуации когда невозможно определить тип значения, которое функция должна вернуть.
VladD2,
> ПК> Влад, это реализуется не сложнее, чем в C++ выбор из перегруженных функций по типу, стоящему в левой части:
> Это сложно реализовать в рамках выбранной граматики языка. Конфликты граматики и неопределенности тоже сложности.
Никаких сложностей в рамках выбранной грамматики тоже нет. Вот пример, наглядно это демонстрирующий:
struct C
{
C( int );
operator int() const;
operator double() const;
};
int main()
{int i = C(10);
double d = C(5);
}
С точки зрения грамматики выделенные строки эквивалентны случаю, если бы C были бы перегруженными по результату функциями.
> Авторы языков не решают нужно или нет.
По крайней мере, в случае C++ можно легко открыть "Дизайн и эволюцию", и убедиться, что подавляющее количество подобных решений начинаются как раз с раздумий, насколько та или иная возможность считается нужной.
Posted via RSDN NNTP Server 1.9 delta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>С точки зрения грамматики выделенные строки эквивалентны случаю, если бы C были бы перегруженными по результату функциями.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Шахтер, Вы писали:
Ш>>Понятно, что в этих случаях разрешение перегрузки по типу возвращаемого значения невозможно,
VD>+1
Ш>> но тогда какая от неё польза? По-видимому -- минимальная.
VD>Чесно говоря хотелось бы поиметь ее в более простых случаях.
VD>Например мне не очень нравятся конструкции вроде: VD>
VD>TypeOfResult result = (TypeOfResult)Query("некоторый запрос");
VD>
VD>Было бы здорово если можно было перегрузить Query по возвращаемому значению. Тогда в него можно было встроить понятное объяснение произошедшей ошибки или еще чего. Ну, и синтаксис стал бы проще.
Ну, собственно, а что мешает использовать технику типа:
using System;
namespace TestSharp
{
class QueryResult {}
class QueryShot
{
string query;
int sendRetErrorCode() { return 12345; }
string sendRetErrorDescription() { return"F**k off"; }
QueryResult sendRetData() { return null; }
public QueryShot(string query_) { query=query_; }
public static implicit operator int(QueryShot x) { return x.sendRetErrorCode(); }
public static implicit operator string(QueryShot x) { return x.sendRetErrorDescription(); }
public static implicit operator QueryResult(QueryShot x) { return x.sendRetData(); }
};
class TestClass
{
static QueryShot Query(string s) { return new QueryShot(s); }
[STAThread]
static void Main(string[] args)
{
string s="SELECT * FROM girls_table";
int error_code=Query(s);
string error_desc=Query(s);
QueryResult res=Query(s);
Console.WriteLine("{0}\n{1}\n{2}",error_code,error_desc,res);
}
}
}
> ПК>Можно. Давно есть в Ada. При желании можно эмулировать в C++ с помощью возвращения прокси-объекта с операциями приведения к соответствующим типам. Как с этим обстоит в C# —
> С++ без всяких проксей >
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Шахтер, Вы писали:
Ш>>Ну, собственно, а что мешает использовать технику типа:
VD>Нарушение безопасности типов и море траха.
Поясни, пожалуйста, где здесь "нарушение безопасности типов". Моря Траха я тоже не наблюдаю.
Здравствуйте, Кодт, Вы писали:
К>Здравствуйте, VladD2, Вы писали:
VD>>А какова по-твоему разница между перегрузкой и переопределением?
К>Ну, у меня возникло подозрение, что LIS спросил про переопределение с возвращением ковариантного типа. К>Если же именно про перегрузку — то тем более нет проблем (в С++).
Чего-то я никак не пойму разницы между перегрузкой и переопределением
Если мы перегрузили функцию, то при принудительном приведении типов (например к базовому) будет вызываться функция приведенного типа.
Здравствуйте, поставившие улыбки на пост Сергея Губанова.
Что, уже одно упоминание Оберона приступ смеха вызывает?
PS. Сам чуть под стол не свалился. Увидев ваши оценки. Но смайл ставить не стал, ибо к содержанию данной ветки это, ИМХО, отношения не имеет.
PPS. Жаль, нет оценки для оценки. Вот туда хотел бы "смешно" поставить.