BZ>>и что возвращает функция int fread(...) ? BZ>>кол-во прочитанных байт? код ошибки? фазу Луны? W>Ну, давайте не заниматься демагогией. Я хотя бы знаю, что это целое. По этому, по названию и сигнатуре функции я в 99% случаев могу предсказать этот результат.
Ну вернет тебе bytes_read == 8 и что же ты знаешь?
* Это прочитано 8 элементов или 4 элемента по 2?
* Это всего прочитано или только до EOF?
* Это успел прочитать какой то огрызок данных до возникновения ошибки?
Здравствуйте, B0FEE664, Вы писали:
BFE>Соответственно вопрос, можно ли использовать результат этой функции в другой единице трансляции?
а причем здесь результат? это зависит от того как функция объявлена, не?
и вообще, программисту должно быть, вообще, плевать на то как компилятор обеспечит видимость какого-то результата, если он объявил саму функцию видимой.
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Здравствуйте, UA, Вы писали: UA>Ну вернет тебе bytes_read == 8 и что же ты знаешь? UA>* Это прочитано 8 элементов или 4 элемента по 2?
Как правило, мне плевать. Если я читаю байты из потока, то мне нужен просто размер. UA>* Это всего прочитано или только до EOF?
Если меня интересует EOF, я лучше спрошу у файла file->eof()? UA>* Это успел прочитать какой то огрызок данных до возникновения ошибки?
Если произошла ошибка, предпочту словить исключение там, где с ним знают что делать, а не прокидывать коды ошибок через всю Ивановскую.
UA>>Ну вернет тебе bytes_read == 8 и что же ты знаешь? UA>>* Это прочитано 8 элементов или 4 элемента по 2? W>Как правило, мне плевать. Если я читаю байты из потока, то мне нужен просто размер. UA>>* Это всего прочитано или только до EOF? W>Если меня интересует EOF, я лучше спрошу у файла file->eof()? UA>>* Это успел прочитать какой то огрызок данных до возникновения ошибки? W>Если произошла ошибка, предпочту словить исключение там, где с ним знают что делать, а не прокидывать коды ошибок через всю Ивановскую.
Ты путаешь подходы низкого и высокого уровней:
* если тебя интересуют байты значит ты на самом низком уровне со всеми вытекающими (когда нету ни эксепшинов, ни уверенности что данные прочитаются в полном объёме, и никаких file->eof() у тебя не будет, а только указатель или хэндл потока);
* если же ты на объектном уровне то читают уже не байтами, а сразу объектами;
Здравствуйте, B0FEE664, Вы писали:
BFE>Здравствуйте, Vain, Вы писали:
BFE>>>Наконец-то можно возвращать структуры определённые внутри, а не вне функции: V>>А в чём трюк то заключается?
BFE>Не знаю как вам, а мне часто хочется написать функцию возвращающую код ошибки осмысленным текстом:
BFE>
__>А чем все-таки вас не устраивает первое решение?
Тем, что приходится объявлять enum или структуру с каким-то именем и это имя засоряет пространство имён. Как правило тип возвращаемого значения создаётся ровно для одной функции, тогда логично в качестве имени взять имя функции и добавить в конце слово Result, как в примере выше. Получается слишком длинно, но это ещё можно пережить. А представьте, что у вас в классе 5 методов возвращающих результат. Получается, что в классе объявляется пять enum'ов только для того, чтобы написать пять функций. Код начинает приобретать монструозный вид, особенно для inline методов в две-три строчки. У программиста читающего такой код начинают возникать вопросы к автору относительно его, автора, психического здоровья. Тогда предпринимаются объединить похожие типы результатов в один тип, что привносит в код путаницу на ровном месте. Например, вскоре оказывается, что хотя функция и возвращает в качестве результата некий enum, но, тем не менее, не все значения этого enum'а могут быть возвращены этой функцией, что в вызывающем коде порождает ещё большую путаницу — либо писать обработчик для значения, которое никогда не будет получено, либо заложится на знание устройства функции, что чревато проблемами при изменении функции...
Здравствуйте, Went, Вы писали:
W>>>1. Кишки функции наружу. BFE>>В каком смысле? То, что определение описано внутри функции, а не снаружи? А typedef key key_type; у std::map — это кишки класса наружу? Нет? Почему? W>Нет, в том смысле, что я не могу реализовать функцию отдельно от декларации.
Хм:
extern auto fun();
Хотите сказать, что это не по стандарту?
W>>>2. Невозможность использовать этот тип где либо еще, объявлять его явно. BFE>>Это плюс, а не минус. Это не позволит перепутать результат функции с чем-то ещё. W>Кому не позволит? Разработчику библиотеки?
Пользователю библиотеки.
W>>>3. Необходимость лезть в реализацию функции для поиска ее возврата. BFE>>С кодами int, bool или "не дай бог" errno() легче что-ли? W>Я хотя бы знаю, что эта функция возвращает, глянув только на ее заголовок.
Но это знание вам мало чего даёт. Что толку от того, что функция возвращает, например, bool ? bool GetButtonState() о чём-нибудь говорит?
BFE>>Например, функция std::stod вместо бросания исключения могла бы возвращать результат, код конвертации и указатель на константную строку с описанием ошибки. W>И вместо W>
W>auto number = std::stod("10.0");
W>
W>Писать W>
W>auto number = std::stod("10.0").result;
W>
W>?
Да.
Только вместо auto
const auto&& result = sstd::stod("10.0");
W>Ведь сейчас никто не мешает так делать. Заведи шаблон со всеми требуемыми полями и пиши себе: W>
Здравствуйте, Vain, Вы писали:
BFE>>Соответственно вопрос, можно ли использовать результат этой функции в другой единице трансляции? V>а причем здесь результат? это зависит от того как функция объявлена, не?
Ну и как следует функцию объявить?
Здравствуйте, B0FEE664, Вы писали:
BFE>Здравствуйте, _hum_, Вы писали:
BFE>>>Не знаю как вам, а мне часто хочется написать функцию возвращающую код ошибки осмысленным текстом:
BFE>>>
__>>А чем все-таки вас не устраивает первое решение?
BFE>Тем, что приходится объявлять enum или структуру с каким-то именем и это имя засоряет пространство имён. Как правило тип возвращаемого значения создаётся ровно для одной функции, тогда логично в качестве имени взять имя функции и добавить в конце слово Result, как в примере выше. Получается слишком длинно, но это ещё можно пережить. А представьте, что у вас в классе 5 методов возвращающих результат. Получается, что в классе объявляется пять enum'ов только для того, чтобы написать пять функций. Код начинает приобретать монструозный вид, особенно для inline методов в две-три строчки. У программиста читающего такой код начинают возникать вопросы к автору относительно его, автора, психического здоровья. Тогда предпринимаются объединить похожие типы результатов в один тип, что привносит в код путаницу на ровном месте. Например, вскоре оказывается, что хотя функция и возвращает в качестве результата некий enum, но, тем не менее, не все значения этого enum'а могут быть возвращены этой функцией, что в вызывающем коде порождает ещё большую путаницу — либо писать обработчик для значения, которое никогда не будет получено, либо заложится на знание устройства функции, что чревато проблемами при изменении функции...
То есть, речь о том, чтобы уметь делать что-то наподобие:
Здравствуйте, B0FEE664, Вы писали:
BFE>>>Соответственно вопрос, можно ли использовать результат этой функции в другой единице трансляции? V>>а причем здесь результат? это зависит от того как функция объявлена, не? BFE>Ну и как следует функцию объявить?
как и раньше наверно — видимой везде.
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Здравствуйте, _hum_, Вы писали:
__>p.s. а что в таких случаях будет с перегружаемыми функциями, наподобие auto f(); auto f(int i); ?
А проблема то в чём ?
Будут разные типы.
#include <iostream>
#include <type_traits>
using namespace std;
auto f()
{
enum class A { X, Y };
return A::X;
}
auto f(int)
{
enum class A { X, Y };
return A::X;
}
int main()
{
auto fvoid = f();
auto fint = f(1);
cout << is_same<decltype(fvoid), decltype(fint)>::value; // 0
}
Здравствуйте, _NN_, Вы писали:
_NN>Здравствуйте, _hum_, Вы писали:
__>>p.s. а что в таких случаях будет с перегружаемыми функциями, наподобие auto f(); auto f(int i); ?
_NN>А проблема то в чём ? _NN>Будут разные типы.
_NN>
_NN>#include <iostream>
_NN>#include <type_traits>
_NN>using namespace std;
_NN>auto f()
_NN>{
_NN> enum class A { X, Y };
_NN> return A::X;
_NN>}
_NN>auto f(int)
_NN>{
_NN> enum class A { X, Y };
_NN> return A::X;
_NN>}
_NN>int main()
_NN>{
_NN> auto fvoid = f();
_NN> auto fint = f(1);
_NN> cout << is_same<decltype(fvoid), decltype(fint)>::value; // 0
_NN>}
_NN>
Вы немного не так поняли. Я-то думал, что речь о том, чтобы задействовать использование идентификатора функции для идентификации типа возвращаемых ею значений (тем самым экономились бы идентификаторы и в то же время обеспечивалась привязка типа к конкретной функции) — эдакой своеобразной инкапсуляции типа в функцию с возможностью явного экспортирования, то есть некоего аналога
struct f
{
enum class Res{ok, failed};
Res operator()(){return Res::ok;}
};
для которого можно
void main()
{
list<f::Res> ResLog;
for(int i = 0; i < 100; ++i)
{
f::Res res = f()();// а хотелось бы f()
ResLog.push_back(res);
};
}
Однако, как в дальнейшем выяснилось, мой вариант невозможен, ибо идентификация области видимости функции по ее имени не уникальна. А изначальный вариант (и ваш его повторяющий) плох тем, что за пределами функции приходится работать с анонимным типом. Соответственно, например, нельзя просто заранее организовать контейнеры для хранения результатов вычислений функции, не говоря уже о том, что читабельность такого варианта плохая.
Здравствуйте, _hum_, Вы писали:
__>Однако, как в дальнейшем выяснилось, мой вариант невозможен, ибо идентификация области видимости функции по ее имени не уникальна. А изначальный вариант (и ваш его повторяющий) плох тем, что за пределами функции приходится работать с анонимным типом. Соответственно, например, нельзя просто заранее организовать контейнеры для хранения результатов вычислений функции, не говоря уже о том, что читабельность такого варианта плохая.
Ну так на то и анонимные типы.
Нужно больше, нужно создавать именованный тип.
Очень редкая ситуация когда один тип ограничен одной функцией.
Здравствуйте, BulatZiganshin, Вы писали:
BZ>в результате получаем просто функцию, возвращающую несколько поименованных результатов
Неудобно тут то, что имена результатов можно узнать только в теле функции. Удобнее, что бы он были видны в хедере...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
BZ>>в результате получаем просто функцию, возвращающую несколько поименованных результатов E>Неудобно тут то, что имена результатов можно узнать только в теле функции. Удобнее, что бы он были видны в хедере...
А такая функция и будет в header, так как результирующий тип выводится.
__>? __>Если да (хотя автор изначально как-то не совсем то излагал), то согласен, полезная штука.
__>p.s. а что в таких случаях будет с перегружаемыми функциями, наподобие auto f(); auto f(int i); ?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>А такая функция и будет в header, так как результирующий тип выводится.
Ну так надо будет ботать код функции, что бы понять чего от ней ждать... В чём профит?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском