Re[8]: Cpp-Object
От: _nn_  
Дата: 20.05.06 17:46
Оценка:
Здравствуйте, MuTPu4, Вы писали:

MTP>Здравствуйте, Воронков Василий, Вы писали:


ВВ>>Это уже не любой тип.

MTP>То есть все проблемы от того, что я не могу передать в функцию с такой сомнительной сигнатурой rvalue или о чем идет речь?

MTP>P.S. Вообще, было бы интересно посмотерть на реализацию функции, "которая будет принимать любой тип".


void f(object const& o)
{
 try
 {
  o.invoke("f", 1); // o.f(1);
 }
 catch(invalid_invoke)
 {
 }
}

Сойдет ?
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[9]: Cpp-Object
От: MuTPu4  
Дата: 20.05.06 18:21
Оценка:
Здравствуйте, _nn_, Вы писали:

__>Сойдет ?

Ясно. Про reflection в исходном сообщении речи не шло, это несколько меняет дело. Хотя, насколько необходима такая функциональности в C++ для меня не очевидно, но в любом случае удачи в этом проекте .
Re[10]: Cpp-Object
От: _nn_  
Дата: 20.05.06 19:02
Оценка:
Здравствуйте, MuTPu4, Вы писали:

MTP>Здравствуйте, _nn_, Вы писали:


__>>Сойдет ?

MTP>Ясно. Про reflection в исходном сообщении речи не шло, это несколько меняет дело. Хотя, насколько необходима такая функциональности в C++ для меня не очевидно, но в любом случае удачи в этом проекте .
Представьте, что можно передавать любой тип, работать с ним, а потом сохранить состояние.
Далее другая программа создает этот тип только из данных в виде байтов и может работать с ним.
(Допустим реализация типа находится в одной библиотеке (Dll), а 2 программы используют ее).
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[11]: Cpp-Object
От: _nn_  
Дата: 20.05.06 19:30
Оценка:
Здравствуйте, _nn_, Вы писали:

__>Здравствуйте, MuTPu4, Вы писали:


MTP>>Здравствуйте, _nn_, Вы писали:


__>>>Сойдет ?

MTP>>Ясно. Про reflection в исходном сообщении речи не шло, это несколько меняет дело. Хотя, насколько необходима такая функциональности в C++ для меня не очевидно__>Представьте, что можно передавать любой тип, работать с ним, а потом сохранить состояние.
__>Далее другая программа создает этот тип только из данных в виде байтов и может работать с ним.
__>(Допустим реализация типа находится в одной библиотеке (Dll), а 2 программы используют ее).
MTP>>, но в любом случае удачи в этом проекте .
Спасибо
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[8]: Cpp-Object
От: Воронков Василий Россия  
Дата: 21.05.06 03:11
Оценка:
Здравствуйте, MuTPu4, Вы писали:

MTP>P.S. Вообще, было бы интересно посмотерть на реализацию функции, "которая будет принимать любой тип".


Шаблонная функция с перегрузкой сойдет?
Re[5]: Cpp-Object
От: LeeMouse Россия  
Дата: 21.05.06 07:33
Оценка:
Здравствуйте, _nn_, Вы писали:
__>Без ссылок там все равно не обойтись.
и что?
__>void f(int& i);
__>Это out или in-out аргумент ?
__>Без документации нельзя узнать.
Хаха*3 Это out-аргумент, ибо не константный. Если константный — то in.
__>А как вы решаете эти проблемы:
__>
__>template<typename T>
__>size_t f(T const& t)
__>{
__> return t.size();
__>}

__>f(1); // не работает.
__>


Неверный код потому и не работает. Это только у Вас такие проблемы, у нас таких нет

__>Обход:

__>
__>template<bool primitive>
__>struct f_impl
__>{
__> template<typename T>
__> static void f(T const& t)
__> {
__>  return sizeof(t);
__> }
__>};

__>template<>
__>struct f_impl<false>
__>{
__> template<typename T>
__> static void f(T const& t)
__> {
__>  return t.size();
__> }
__>};

__>template<typename T>
__>size_t f(T const& t)
__>{
__> return f_impl<is_primitive<T>::value>::f(t);

__>f(1); // теперь работает
__>

__>А можно ведь было:
__>
__>size_t f(object& t)
__>{
__> return t.size();
__>}
__>




__>Смотрите выше.


Изучите библиотеку "Boost Concept Check Library (BCCL)" — и проблема отпадёт сама.
Хотя при большом Вашем желании она (проблема) может у Вас и остаться...
Re[2]: C++ Object продолжение
От: igna Россия  
Дата: 21.05.06 09:50
Оценка:
Здравствуйте, _nn_, Вы писали:

__>void f(in<int> x); // <=> void f(int x);


А если имеем класс X определенный как

class X {
    int a[1000];
};

, то

void f(in<X> x); // <=> void f(X x);

или

void f(in<X> x); // <=> void f(X const& x);

?
Re: Cpp-Object
От: Кодт Россия  
Дата: 21.05.06 13:27
Оценка: 6 (1)
Здравствуйте, _nn_, Вы писали:

Про in/out-параметры мысль есть:
Семантика взаимодействия вызывающей и вызываемой сторон не исчерпывается примитивами in/out/inout, так же как и value/reference/const_reference.
Devil in details — примитивы маскируют замысел, что потворствует ошибкам.

Как оно бывает на самом деле:

Далее — вызывающая и вызываемая стороны именуются клиентом и сервером, для краткости.
Примеры — на С++, хотя без труда их можно перевести на практически любой язык.
Если кого-то возмущают глобальные переменные — представьте себе, что это всё члены одного объекта одного класса. И клиент, и сервер — методы этого объекта.
Я привожу дистиллированные примеры для краткости и ясности; в жизни всё может выглядеть не так прозрачно, хотя и с теми же самыми эффектами.



1) Рандеву. Клиент и сервер выполняют совместную работу над одним экземпляром данных. Серверу может быть предоставлен некоторый интерфейс объекта (например, только константные члены).
void foo(ostream& ost)
// очевидно, что ostream - не value-тип, поэтому говорить об inout здесь сложно
// (значение туда-сюда не передаётся)
{
  ost << "hello";
  cout << endl;
  // в результате, если ost и cout - одно лицо, то ost будет очищен (endl вызывает flush)
}

Как клиент может выполнять совместную работу? да через callback-функции, например. Или ещё через какие-то побочные эффекты.

Самая простая и естественная реализация — передача по ссылке (константной или нет).

2) Передача значения. Клиент рассчитывает, что сервер разрывает связь между клиентским и серверным экземплярами данных.
Сервер не может модифицировать клиентский объект. Модификации клиентского объекта не отражаются на сервере.
// дистиллированный пример модификации (вместо int можете подставить какой-нибудь тяжеловесный объект)
void foo(int /*const&*/ fnf, int* hack) // раскомментируйте, чтобы взорвалось
{
  int x = fnf;
  ++(*hack);
  int y = fnf;
  assert(x == y);
}
int main()
{
  int x;
  foo(x, &x);
}

Самая простая реализация — принудительное создание копии (aka передача по значению). И поэтому иногда неэффективная.
Во многих случаях достаточно передавать по константной ссылке (причём обе стороны должны соблюдать аккуратность).
Изощрённая реализация — механизм copy-on-write. То есть объект передаётся посредством умной ссылки, и любая попытка модификации приводит к расщеплению копий.

3) Обязательное возвращение значения.
Если экземпляр клиента уже существует, то он заведомо не совпадает с экземпляром сервера, откуда происходит однократная передача значения.
string g;
string foo()
{
  string tmp = "(";
  tmp += g;
  tmp += ")";
  return tmp;
}
void foo2(string& dst) // по неопытности сделали рандеву
{
  dst = "[";
  dst += g;
  dst += "]";
}
void foo3(string& dst)
{
  string tmp = "{";
  tmp += g;
  tmp += "}";
  // ошибочка (см.ниже)
}
void foo4(string& dst)
{
  string tmp = "{";
  tmp += g;
  tmp += "}";
  dst = tmp;
}
int main()
{
  g = "hello";

  g = foo(); // "(hello)"

  // пример практически идентичен предыдущему: там тоже создаётся временный объект
  string tmp; foo2(tmp); g = tmp; // "[(hello)]";

  // а вот пример некорректной реализации: не обеспечили изоляцию
  foo2(g); // "[[]";

  // багфикс на стороне сервера
  foo3(g); // "[[]" - изолировать изолировали, а присвоить в конце забыли
  foo4(g); // "{[[]}" - теперь всё правильно
}

Языки обеспечивают изоляцию через временный объект (размещённый на стеке или в регистре — не важно) и иногда позволяют оптимизировать копирование (RVO, NRVO). Но только для единственного параметра (return) и исключительно по прихоти компилятора.
Чистоплотный выход — возвращать кортежи вместо разрозненных retval-параметров — может стоить довольно дорого и не всегда удобен.
pair<string,int> foo()
{
  string s = "{";
  s += rand()%2 ? "hello" : "goodbye";
  s += "}";
  int x = s.size();
  return make_pair(s,x);
}
int main()
{
  string s; int x;
  tie(s,x) = foo();
}


4) Необязательное возвращение значения.
Отличается от предыдущего тем, что значение может быть присвоено от 0 до 1 раза, по обстоятельствам.
Посредством return такое уже выразить сложно — разве что через бросок исключения.

Самая простая реализация — передавать ссылку и быть аккуратным.

5) Наконец, загадочный in-out. За ним может скрываться либо рандеву, либо экономичный способ сделать передачу исходного значения и обязательное/необязательное возвращение нового значения.



Обёртки параметров играют две роли
— обеспечивают подходящий транспорт (передачу копии или ссылки; COW и отложенное присваивание)
— выполняют проверки (было ли присвоено значение out-параметру, например)
Перекуём баги на фичи!
Re[3]: C++ Object продолжение
От: Roman Odaisky Украина  
Дата: 21.05.06 17:44
Оценка:
boost::call_traits?
До последнего не верил в пирамиду Лебедева.
Re[8]: Cpp-Object
От: Pavel Chikulaev Россия  
Дата: 22.05.06 16:13
Оценка:
Здравствуйте, Centaur, Вы писали:

C>Здравствуйте, Pavel Chikulaev, Вы писали:


C>
int * f(int *);


PC>>И что делать с обоими указателями? Удалять или нет?


C>Если это C++, а не C, то тут довольно понятно.

C>Если бы функция хотела, чтобы мы отдали ей int во владение, она бы принимала auto_ptr<int>. Раз оно не так, мы должны его убить сами. Напротив, если бы функция хотела вернуть нам int, чтобы мы его потом удалили, она бы вернула его через auto_ptr<int>. Это не так, значит, вернутый указатель не наш, и удалять его не нам

+1. Или shared_ptr. Но обычно следует передавать ссылку если не происходит передача владения и объект всегда существует.

Только библиотек, в которых применяется это правило не так много (а точнее очень мало), так что документацию на всякий случай придется посмотреть (часто даже там не пишут про это : ( ). А хотелось бы этого не делать...
Re[3]: C++ Object продолжение
От: _nn_  
Дата: 22.05.06 17:13
Оценка:
Здравствуйте, igna, Вы писали:

I>Здравствуйте, _nn_, Вы писали:


I>
__>>void f(in<int> x); // <=> void f(int x);
I>


I>А если имеем класс X определенный как


I>
I>class X {
I>    int a[1000];
I>};
I>

I>, то

I>
I>void f(in<X> x); // <=> void f(X x);
I>

I>или

I>
I>void f(in<X> x); // <=> void f(X const& x);
I>

I>?

ССылкой, зачем передавать объект по значению ?
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[2]: C++ Object продолжение
От: sergey_shandar США http://getboost.codeplex.com/
Дата: 23.05.06 04:03
Оценка:
Здравствуйте, _nn_, Вы писали:

__>Спасибо всем за комментарии.


__>4. Унифицированная передача аргументов.


Раз пошла такая пьянка, то как на счет типа результата функции? В COM обычно это оформляется как out<T>. Но, такой синтаксис
void GetProperty(out<int> &i);

int i;
GetProperty(i);
if(i==5) ...

мягко говоря, не очень приятный. Если out<T> это оболочка над T &, то:
out<T> GetProperty()

не подойдет. Как насчет result&lt;T&gt;
Автор: sergey_shandar
Дата: 11.01.06
?
getboost.codeplex.com
citylizard.codeplex.com
Re[3]: C++ Object продолжение
От: _nn_  
Дата: 25.05.06 17:09
Оценка:
Здравствуйте, sergey_shandar, Вы писали:

_>Здравствуйте, _nn_, Вы писали:


__>>Спасибо всем за комментарии.


__>>4. Унифицированная передача аргументов.


_>Раз пошла такая пьянка, то как на счет типа результата функции? В COM обычно это оформляется как out<T>. Но, такой синтаксис

_>
_>void GetProperty(out<int> &i);

_>int i;
_>GetProperty(i);
_>if(i==5) ...
_>

_>мягко говоря, не очень приятный. Если out<T> это оболочка над T &, то:
_>
_>out<T> GetProperty()
_>

_>не подойдет. Как насчет result&lt;T&gt;
Автор: sergey_shandar
Дата: 11.01.06
?


Это тоже в планах.
Раз вы затронули эту тему то вопрос:
Насколько можно сделать перемещение эксклюзивным, т.е. без изменения самого класса ?

Идеальный вариант:
struct a
{
 void q(){}
};

ret<a> f()
{
 a x;
 x.q();
 return x;
}

int main()
{
 a y(f());
}
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[4]: C++ Object продолжение
От: sergey_shandar США http://getboost.codeplex.com/
Дата: 27.05.06 18:24
Оценка: 1 (1)
Здравствуйте, _nn_, Вы писали:

__>Насколько можно сделать перемещение эксклюзивным, т.е. без изменения самого класса ?


struct a
{
 void q(){}
};

move_t<a> f()
{
 a x;
 x.q();
 // Создание - явное, защита от самого себя :-)
 return move(x);
}

int main()
{
 // move_t использует swap, поэтому для обмена нужно сначала создать объект.
 // Если без изменения класса, то только так (я не знаю других вариантов эффективных):
 a y;
 move_ref(y) = f();

 // Или создавая сразу уже move_t<a> и используя операторы * и ->
 move_t<a> y1(f());
}


См: http://www.rsdn.ru/Forum/?mid=1585748
Автор: sergey_shandar
Дата: 12.01.06
. Последний вариант http://svn.berlios.de/viewcvs/cbear/trunk/cbear.berlios.de/base/swap.hpp?view=markup.
getboost.codeplex.com
citylizard.codeplex.com
Re[5]: C++ Object продолжение
От: _nn_  
Дата: 27.05.06 18:58
Оценка:
Здравствуйте, sergey_shandar, Вы писали:

_>Здравствуйте, _nn_, Вы писали:


__>>Насколько можно сделать перемещение эксклюзивным, т.е. без изменения самого класса ?


_>
_>struct a
_>{
_> void q(){}
_>};

_>move_t<a> f()
_>{
_> a x;
_> x.q();
_> // Создание - явное, защита от самого себя :-)
_> return move(x);
_>}

_>int main()
_>{
_> // move_t использует swap, поэтому для обмена нужно сначала создать объект.
_> // Если без изменения класса, то только так (я не знаю других вариантов эффективных):
_> a y;
_> move_ref(y) = f();

_> // Или создавая сразу уже move_t<a> и используя операторы * и ->
_> move_t<a> y1(f());
_>}
_>


Тут можно пойти еще по другому пути создать тип переменной, которая перемещаемая (moveable):
ret<string> f(in<string> s)
{
 var<string> s2(s + " "); 
 return s2; // implicit ret<T>::ret(var<T>)

 // Аналогично
 // string s2(s + " ");
 // return move(s2);
}


_>См: http://www.rsdn.ru/Forum/?mid=1585748
Автор: sergey_shandar
Дата: 12.01.06
. Последний вариант http://svn.berlios.de/viewcvs/cbear/trunk/cbear.berlios.de/base/swap.hpp?view=markup.


Скажите, какая лицензия у этого кода ?
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[6]: C++ Object продолжение
От: sergey_shandar США http://getboost.codeplex.com/
Дата: 27.05.06 19:13
Оценка:
Здравствуйте, _nn_, Вы писали:

Тут можно пойти еще по другому пути создать тип переменной, которая перемещаемая (moveable):
move_t<string> f(in<string> s)
{
 move_t<string> s2(s + " "); 
 return s2; // implicit ret<T>::ret(var<T>)
}

Да, конечно. Одного типа move_t достаточно.

_>>См: http://www.rsdn.ru/Forum/?mid=1585748
Автор: sergey_shandar
Дата: 12.01.06
. Последний вариант http://svn.berlios.de/viewcvs/cbear/trunk/cbear.berlios.de/base/swap.hpp?view=markup.


__>Скажите, какая лицензия у этого кода ?


MIT. Близкая к BSD и Boost. Не GPL
getboost.codeplex.com
citylizard.codeplex.com
Re[7]: C++ Object продолжение
От: _nn_  
Дата: 27.05.06 19:17
Оценка:
Здравствуйте, sergey_shandar, Вы писали:

_>Здравствуйте, _nn_, Вы писали:


_>Тут можно пойти еще по другому пути создать тип переменной, которая перемещаемая (moveable):

_>
_>move_t<string> f(in<string> s)
_>{
_> move_t<string> s2(s + " "); 
_> return s2; // implicit ret<T>::ret(var<T>)
_>}
_>

_>Да, конечно. Одного типа move_t достаточно.

Здесь я хотел чтобы была синтаксическая разница.
Т.е.
var — переменная
ret — возвращаемое значение

Аналогично
out vs. inout

_>>>См: http://www.rsdn.ru/Forum/?mid=1585748
Автор: sergey_shandar
Дата: 12.01.06
. Последний вариант http://svn.berlios.de/viewcvs/cbear/trunk/cbear.berlios.de/base/swap.hpp?view=markup.


__>>Скажите, какая лицензия у этого кода ?


_>MIT. Близкая к BSD и Boost. Не GPL

Я не очень силен в лицензиях.
Могу ли я этот код немного изменить для общего стиля библиотеки ?
Авторство будет сохраненно.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[8]: C++ Object продолжение
От: sergey_shandar США http://getboost.codeplex.com/
Дата: 27.05.06 19:22
Оценка:
Здравствуйте, _nn_, Вы писали:

_>>MIT. Близкая к BSD и Boost. Не GPL

__>Я не очень силен в лицензиях.
__>Могу ли я этот код немного изменить для общего стиля библиотеки ?
Да, все что угодно. Главное что бы ко мне никаких претензий, если из за этого куска кода у кого то деньги со счета не пропали и т.п.
getboost.codeplex.com
citylizard.codeplex.com
Re[9]: C++ Object продолжение
От: _nn_  
Дата: 27.05.06 19:35
Оценка:
Здравствуйте, sergey_shandar, Вы писали:

_>Здравствуйте, _nn_, Вы писали:


_>>>MIT. Близкая к BSD и Boost. Не GPL

__>>Я не очень силен в лицензиях.
__>>Могу ли я этот код немного изменить для общего стиля библиотеки ?
_>Да, все что угодно. Главное что бы ко мне никаких претензий, если из за этого куска кода у кого то деньги со счета не пропали и т.п.
Ок, включу в библиотеку.
Хотите я вас в разработчики добавлю ?

На данный момент будут следущие типы:
  • in — для входных аргументов
  • out — для выходных аргументов
  • inout — для входных и выходных аргументов
  • ref — для ссылки на out/inout
  • cref — для ссылки на in (inout ?)
  • ret — для возврата функций
  • var — для обычных переменных

    Думаете стоит еще что-нибудь добавить ?
  • http://rsdn.nemerleweb.com
    http://nemerleweb.com
    Re[10]: C++ Object продолжение
    От: sergey_shandar США http://getboost.codeplex.com/
    Дата: 27.05.06 20:20
    Оценка:
    Здравствуйте, _nn_, Вы писали:

    __>Хотите я вас в разработчики добавлю ?

    На форума вашего проекта cpp-objects в Open Discussion есть встречное предложение Отвечайте туда, что бы не засорять RSDN.
    getboost.codeplex.com
    citylizard.codeplex.com
    Подождите ...
    Wait...
    Пока на собственное сообщение не было ответов, его можно удалить.