Re: Реализация IN, IN-OUT и OUT параметров функций
От: Galiulin Rishat Faimovich Узбекистан  
Дата: 14.09.11 13:16
Оценка:
Спасибо всем кто ответил.

Хочу подробнее описать причину использования именно этой модели, а не стандартной и не модели с define-ами:
  1. С помошью стандартной модели можно реализовать все три типа параметров, но в местах вызова функций непонятно передается параметр по ссылке или по значению. Также для стандартной модели существует неавное приведение типов.
  2. Для define-ов, так как они являются просто заглушками, характерны все высше перечисленные недостатки. К ним еще прибавляется несинхронизированность между вставленными IN, IN_OUT и OUT "украшательсвами" и реальными характеристиками параметров в результате частых изменений кода.

На синтетических тестах модель вроде бы работает. Мы бы очень хотели узнать узкие места такой реализации.
Re[5]: Реализация IN, IN-OUT и OUT параметров функций
От: MasterZiv СССР  
Дата: 14.09.11 21:00
Оценка:
On 09/14/2011 01:33 PM, Аноним 20 wrote:

> Нет не при передаче больших структур а именно при передаче по ссылке или указателю.

> Думаю шаблоны дают компилятору какую-то дополнительную информацию о типе и по
> этой пирине он убирает излишние проверки.

Ну это не очень похоже на правду.
Posted via RSDN NNTP Server 2.1 beta
Re[2]: Реализация IN, IN-OUT и OUT параметров функций
От: MasterZiv СССР  
Дата: 14.09.11 21:01
Оценка:
On 09/14/2011 12:45 PM, Аноним 504 wrote:

> GRF> *function_3( in< short*>(&InShort ), in_out< int*>( pInOutInteger ) , out< int*>( pInOutInteger ) );*


> И вот это по вашему легче читаемо?

> Не, ну этож песец на ровном месте такие огороды городить.

Я того же мнения.
Posted via RSDN NNTP Server 2.1 beta
Re[2]: Реализация IN, IN-OUT и OUT параметров функций
От: MasterZiv СССР  
Дата: 14.09.11 21:08
Оценка: 1 (1)
On 09/14/2011 05:16 PM, Galiulin Rishat Faimovich wrote:

> Хочу подробнее описать причину использования именно этой модели, а не

> стандартной и не модели с define-ами:
>
> 1. С помошью стандартной модели можно реализовать все три типа параметров, но
> в местах вызова функций непонятно передается параметр по ссылке или по
> значению. Также для стандартной модели существует неавное приведение типов.
> 2. Для define-ов, так как они являются просто заглушками, характерны все
> высше перечисленные недостатки. К ним еще прибавляется
> несинхронизированность между вставленными IN, IN_OUT и OUT
> "украшательсвами" и реальными характеристиками параметров в результате
> частых изменений кода.

Не, мне это всё лично не нравится. Нагорожен огород, а зачем, не понятно.
В С++ и так нужно всё время смотреть, как используются параметры внутри
функции, меняются или нет, либо в коде, либо в спецификации на функцию.
Ничего страшного тут нет.
Я лучше бы предпочёл смотреть куда-то при необходимости, чем писать
такие вот конструктивы.

Вообще, функция и параметры должны называться так, чтобы и так было всё
понятно.
Posted via RSDN NNTP Server 2.1 beta
Re[3]: Реализация IN, IN-OUT и OUT параметров функций
От: Galiulin Rishat Faimovich Узбекистан  
Дата: 15.09.11 06:19
Оценка:
Здравствуйте, MasterZiv, Вы писали:

MZ>On 09/14/2011 05:16 PM, Galiulin Rishat Faimovich wrote:


>> Хочу подробнее описать причину использования именно этой модели, а не

>> стандартной и не модели с define-ами:
>>
>> 1. С помошью стандартной модели можно реализовать все три типа параметров, но
>> в местах вызова функций непонятно передается параметр по ссылке или по
>> значению. Также для стандартной модели существует неавное приведение типов.
>> 2. Для define-ов, так как они являются просто заглушками, характерны все
>> высше перечисленные недостатки. К ним еще прибавляется
>> несинхронизированность между вставленными IN, IN_OUT и OUT
>> "украшательсвами" и реальными характеристиками параметров в результате
>> частых изменений кода.

MZ>Не, мне это всё лично не нравится. Нагорожен огород, а зачем, не понятно.

MZ>В С++ и так нужно всё время смотреть, как используются параметры внутри
MZ>функции, меняются или нет, либо в коде, либо в спецификации на функцию.
MZ>Ничего страшного тут нет.
MZ>Я лучше бы предпочёл смотреть куда-то при необходимости, чем писать
MZ>такие вот конструктивы.

MZ>Вообще, функция и параметры должны называться так, чтобы и так было всё

MZ>понятно.

Спасибо за ваше мнение.
Re: Реализация IN, IN-OUT и OUT параметров функций
От: DarkTranquillity  
Дата: 16.09.11 05:24
Оценка:
Здравствуйте, Galiulin Rishat Faimovich.

Я конечно извиняюсь и может чего-то недопонимаю, но с каких это пор код с шаблонами стал читабельнее?
Да и просто сравните длину в символах обычного написания и вашей разработки.
Re[2]: Реализация IN, IN-OUT и OUT параметров функций
От: Galiulin Rishat Faimovich Узбекистан  
Дата: 16.09.11 06:28
Оценка:
Здравствуйте, DarkTranquillity, Вы писали:

DT>Здравствуйте, Galiulin Rishat Faimovich.


DT>Я конечно извиняюсь и может чего-то недопонимаю, но с каких это пор код с шаблонами стал читабельнее?

DT>Да и просто сравните длину в символах обычного написания и вашей разработки.

Да я согласен что длина написания немного увеличилась. Но все же как мне кажется читать код стало легче.
Повторю с пример, который я уже написал:
int main( int argc, char **argv )
{
int Integer = argc;
short InShort = Integer * 2;
int InOutInteger = InShort * 3;
std::string InString( "std::string" );
std::string* pInOutString = &InString;
int* pInOutInteger = &InOutInteger;
Base b;
Derived d;

function_0( b );
function_0( in< Base& >( b ) );

function_0( d );
function_0( in< Base& >( d ) );

function_1( &InString, InOutInteger );
function_1( in< std::string* >( &InString ), in_out< int >( InOutInteger ) );

function_2( InShort, pInOutString );
function_2( in< short >( InShort ), in_out< std::string* >( pInOutString ) );

function_3( &InShort, pInOutInteger, &pInOutInteger );
function_3( in< short* >( &InShort ), in_out< int* >( pInOutInteger ) , out< int* >( pInOutInteger ) );
}
[/ccode]

Для того чтобы понять что примерно делает
function_0( b );

или
function_0( d );

с параметром читающему код необходимо посмотреть объявление функции.

Теперь посмотрите на эти вызовы:
function_0( in< Base& >( b ) );

или
function_0( in< Base& >( d ) );

Здесь даже без просмотра объявления функции ясно что параметр не будет изменен функцией, а так же что он будет передан по ссылке (не произойдет срезка).
Re: Реализация IN, IN-OUT и OUT параметров функций
От: LaptevVV Россия  
Дата: 16.09.11 06:39
Оценка:
Здравствуйте, Galiulin Rishat Faimovich, Вы писали:

GRF>Во многих языках есть поддержка со стороны языка IN, IN-OUT и OUT параметров, но в С++ такой нет вместо этого приходиться ипользовать константные и неконстантные ссылки и/или указатели. Поэтому я со своими коллегами решили что лучше было бы их раработать самим. В результате получилась такая реализация, но мы в ней не совсем уверены и хотели бы узнать мнение сообщества:


Мы поступили по-другому. Параметр может быть либо переменной, либо константой — по аналогии с объявлением переменных и констант в программе.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[2]: Реализация IN, IN-OUT и OUT параметров функций
От: Galiulin Rishat Faimovich Узбекистан  
Дата: 16.09.11 07:57
Оценка:
Здравствуйте, LaptevVV, Вы писали:

LVV>Здравствуйте, Galiulin Rishat Faimovich, Вы писали:


GRF>>Во многих языках есть поддержка со стороны языка IN, IN-OUT и OUT параметров, но в С++ такой нет вместо этого приходиться ипользовать константные и неконстантные ссылки и/или указатели. Поэтому я со своими коллегами решили что лучше было бы их раработать самим. В результате получилась такая реализация, но мы в ней не совсем уверены и хотели бы узнать мнение сообщества:


LVV>Мы поступили по-другому. Параметр может быть либо переменной, либо константой — по аналогии с объявлением переменных и констант в программе.


Покажите, пожалуйста, примеры используя вашу нотацию.
Re: Реализация IN, IN-OUT и OUT параметров функций
От: k.o. Россия  
Дата: 16.09.11 08:54
Оценка:
Здравствуйте, Galiulin Rishat Faimovich, Вы писали:

GRF>Во многих языках есть поддержка со стороны языка IN, IN-OUT и OUT параметров, но в С++ такой нет вместо этого приходиться ипользовать константные и неконстантные ссылки и/или указатели. Поэтому я со своими коллегами решили что лучше было бы их раработать самим. В результате получилась такая реализация, но мы в ней не совсем уверены и хотели бы узнать мнение сообщества:


Бессмысленный и беспощадный overdesign, который, к тому же, не всегда работает:

class A
{
};

void sink1(std::unique_ptr<const A> arg)
{
}

void sink2(in<std::unique_ptr<const A>> arg)
{
}

int main()
{
  std::unique_ptr<A> p1(new A);

  sink1(std::move(p1)); // ok

  std::unique_ptr<A> p2(new A);

  sink2(in<std::unique_ptr<const A>>(std::move(p2))); // error
}


и не всегда применим:

MyType z = in<MyType&>(in<MyType&>(a) + in<MyType&>(in<MyType&>(b) * in<MyType&>(c)));


во что это превратится с использованием expression templates я даже думать не хочу, впрочем, как я понял, некоторым такой вариант кажется более читабельным по сравнению с

MyType z = a + b * c;
Re[2]: Реализация IN, IN-OUT и OUT параметров функций
От: Galiulin Rishat Faimovich Узбекистан  
Дата: 16.09.11 13:03
Оценка:
Здравствуйте, k.o., Вы писали:

KO>Здравствуйте, Galiulin Rishat Faimovich, Вы писали:


GRF>>Во многих языках есть поддержка со стороны языка IN, IN-OUT и OUT параметров, но в С++ такой нет вместо этого приходиться ипользовать константные и неконстантные ссылки и/или указатели. Поэтому я со своими коллегами решили что лучше было бы их раработать самим. В результате получилась такая реализация, но мы в ней не совсем уверены и хотели бы узнать мнение сообщества:


KO>Бессмысленный и беспощадный overdesign, который, к тому же, не всегда работает:


KO>
KO>class A
KO>{
KO>};

KO>void sink1(std::unique_ptr<const A> arg)
KO>{
KO>}

KO>void sink2(in<std::unique_ptr<const A>> arg)
KO>{
KO>}

KO>int main()
KO>{
KO>  std::unique_ptr<A> p1(new A);

KO>  sink1(std::move(p1)); // ok

KO>  std::unique_ptr<A> p2(new A);

KO>  sink2(in<std::unique_ptr<const A>>(std::move(p2))); // error
KO>}
KO>


В нашей нотации необходимо несколько изменить вызов и определение:
class A
{
};

void sink1( const std::unique_ptr< const A > arg)
{
}

void sink2( in< std::unique_ptr< const A >& > arg)
{
}

int main( int argc, char **argv )
{
  std::unique_ptr< A > p1( new A );
  sink1( std::move( p1 ) ); // ok

  std::unique_ptr< A > p2( new A );
  sink2( in< std::unique_ptr< const A >& >( std::move( p2 ) ) ); // ok

  return 0;
}


KO>и не всегда применим:


KO>
KO>MyType z = in<MyType&>(in<MyType&>(a) + in<MyType&>(in<MyType&>(b) * in<MyType&>(c)));
KO>


KO>во что это превратится с использованием expression templates я даже думать не хочу, впрочем, как я понял, некоторым такой вариант кажется более читабельным по сравнению с


KO>
KO>MyType z = a + b * c;
KO>


Мы и не планировали что in, in_out и out будут так применяться .
Посмотрите, пожалуйста, примеры использования в самом первом сообщении .
Re[3]: Реализация IN, IN-OUT и OUT параметров функций
От: DarkTranquillity  
Дата: 16.09.11 13:16
Оценка:
Здравствуйте, Galiulin Rishat Faimovich, Вы писали:

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


DT>>Здравствуйте, Galiulin Rishat Faimovich.


DT>>Я конечно извиняюсь и может чего-то недопонимаю, но с каких это пор код с шаблонами стал читабельнее?

DT>>Да и просто сравните длину в символах обычного написания и вашей разработки.

GRF>Да я согласен что длина написания немного увеличилась. Но все же как мне кажется читать код стало легче.

GRF>Для того чтобы понять что примерно делает
GRF>
GRF>function_0( b );
GRF>

GRF>или
GRF>
GRF>function_0( d );
GRF>

GRF>с параметром читающему код необходимо посмотреть объявление функции.

GRF>Теперь посмотрите на эти вызовы:

GRF>
GRF>function_0( in< Base& >( b ) );
GRF>

GRF>или
GRF>
GRF>function_0( in< Base& >( d ) );
GRF>

GRF>Здесь даже без просмотра объявления функции ясно что параметр не будет изменен функцией, а так же что он будет передан по ссылке (не произойдет срезка).

Хм.. а я думал, что еще лучше прикидывать, что делает функция, исходя из ее названия(грамотного, естессно).
По типу параметра, честно, даже в голову не приходило.
Что делает функция f(<in> x) или f(<out> x)?
Еще раз повторюсь, а ниже коллега это подмечает — для Вас шаблоны выглядят читабельнее обычного кода?
Re[4]: Реализация IN, IN-OUT и OUT параметров функций
От: Galiulin Rishat Faimovich Узбекистан  
Дата: 16.09.11 13:55
Оценка:
Здравствуйте, DarkTranquillity, Вы писали:

DT>Здравствуйте, Galiulin Rishat Faimovich, Вы писали:


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


DT>>>Здравствуйте, Galiulin Rishat Faimovich.


DT>>>Я конечно извиняюсь и может чего-то недопонимаю, но с каких это пор код с шаблонами стал читабельнее?

DT>>>Да и просто сравните длину в символах обычного написания и вашей разработки.

GRF>>Да я согласен что длина написания немного увеличилась. Но все же как мне кажется читать код стало легче.

GRF>>Для того чтобы понять что примерно делает
GRF>>
GRF>>function_0( b );
GRF>>

GRF>>или
GRF>>
GRF>>function_0( d );
GRF>>

GRF>>с параметром читающему код необходимо посмотреть объявление функции.

GRF>>Теперь посмотрите на эти вызовы:

GRF>>
GRF>>function_0( in< Base& >( b ) );
GRF>>

GRF>>или
GRF>>
GRF>>function_0( in< Base& >( d ) );
GRF>>

GRF>>Здесь даже без просмотра объявления функции ясно что параметр не будет изменен функцией, а так же что он будет передан по ссылке (не произойдет срезка).

DT>Хм.. а я думал, что еще лучше прикидывать, что делает функция, исходя из ее названия(грамотного, естессно).

DT>По типу параметра, честно, даже в голову не приходило.
DT>Что делает функция f(<in> x) или f(<out> x)?
DT>Еще раз повторюсь, а ниже коллега это подмечает — для Вас шаблоны выглядят читабельнее обычного кода?

Иногда да , например: xxx_cast< T >, to< T >
Re: Реализация IN, IN-OUT и OUT параметров функций
От: Аноним  
Дата: 16.09.11 17:06
Оценка: +2
Здравствуйте, Galiulin Rishat Faimovich, Вы писали:

Я за такое избил бы коллегу клавиатурой. Это называется "синдром засирания всего кода ради ничтожной цели". Эта болезнь часто поражает начинающих программистов на C++ — неумение оценивать отношение важности задачи и сложности решения, сосредоточенность на второстепенных вещах, а также на коде вместо самой задачи. У меня тоже было что-то подобное.

Эта проблема — указание направления параметра, — не является такой серьезной, чтобы ради нее так изуродовать всю программу, катастрофически увеличить время компиляции, размер исполняемых файлов и превратить отладку в ад (даже в функцию отладчиком нормально будет не зайти).

И в любом случае нет необходимости указывать указывать направление "in" — оно и так понятно "по умолчанию", и в нормально написанных программах встречается в 99,99% случаев.
Re[3]: Реализация IN, IN-OUT и OUT параметров функций
От: k.o. Россия  
Дата: 16.09.11 19:04
Оценка:
Здравствуйте, Galiulin Rishat Faimovich, Вы писали:

GRF>Здравствуйте, k.o., Вы писали:


KO>>Здравствуйте, Galiulin Rishat Faimovich, Вы писали:


GRF>>>Во многих языках есть поддержка со стороны языка IN, IN-OUT и OUT параметров, но в С++ такой нет вместо этого приходиться ипользовать константные и неконстантные ссылки и/или указатели. Поэтому я со своими коллегами решили что лучше было бы их раработать самим. В результате получилась такая реализация, но мы в ней не совсем уверены и хотели бы узнать мнение сообщества:


KO>>Бессмысленный и беспощадный overdesign, который, к тому же, не всегда работает:


KO>>
KO>>class A
KO>>{
KO>>};

KO>>void sink1(std::unique_ptr<const A> arg)
KO>>{
KO>>}

KO>>void sink2(in<std::unique_ptr<const A>> arg)
KO>>{
KO>>}

KO>>int main()
KO>>{
KO>>  std::unique_ptr<A> p1(new A);

KO>>  sink1(std::move(p1)); // ok

KO>>  std::unique_ptr<A> p2(new A);

KO>>  sink2(in<std::unique_ptr<const A>>(std::move(p2))); // error
KO>>}
KO>>


GRF>В нашей нотации необходимо несколько изменить вызов и определение:


И получить другое поведение? Нет уж, так не пойдёт, боюсь, небольшим изменением тут не отделаться.

KO>>и не всегда применим:


KO>>
KO>>MyType z = in<MyType&>(in<MyType&>(a) + in<MyType&>(in<MyType&>(b) * in<MyType&>(c)));
KO>>


KO>>во что это превратится с использованием expression templates я даже думать не хочу, впрочем, как я понял, некоторым такой вариант кажется более читабельным по сравнению с


KO>>
KO>>MyType z = a + b * c;
KO>>


GRF>Мы и не планировали что in, in_out и out будут так применяться .


А как же ещё им применяться? Входные параметры есть, почему их не надо помечать? Впрочем, я, кажется, понимаю: благодаря удачным названиям функций способ использования передаваемых параметров очевиден, может, тогда, вместо изобретения велосипедов, стоит давать более удачные названия функциям?
Re[2]: Реализация IN, IN-OUT и OUT параметров функций
От: Galiulin Rishat Faimovich Узбекистан  
Дата: 16.09.11 19:10
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Galiulin Rishat Faimovich, Вы писали:


А>Я за такое избил бы коллегу клавиатурой. Это называется "синдром засирания всего кода ради ничтожной цели". Эта болезнь часто поражает начинающих программистов на C++ — неумение оценивать отношение важности задачи и сложности решения, сосредоточенность на второстепенных вещах, а также на коде вместо самой задачи. У меня тоже было что-то подобное.


А>Эта проблема — указание направления параметра, — не является такой серьезной, чтобы ради нее так изуродовать всю программу, катастрофически увеличить время компиляции, размер исполняемых файлов и превратить отладку в ад (даже в функцию отладчиком нормально будет не зайти).


А>И в любом случае нет необходимости указывать указывать направление "in" — оно и так понятно "по умолчанию", и в нормально написанных программах встречается в 99,99% случаев.


Спасибо за ваше мнение. Я действительно пишу на С++ довольно короткое время — всего 1 год, до этого я писал на Java. Идея ввести IN, IN-OUT и OUT параметры вначале мне тоже не понравилась, и в начале мы хотели ввести параметры просто как define-ы. Но решающим для меня доводом от коллег было то, что новичкам будет легче понять уже существующий код, если ввести такие "подсказки". Я пошел немного дальше и решил возложить проверку параметров также на компилятор.
Re[4]: Реализация IN, IN-OUT и OUT параметров функций
От: Galiulin Rishat Faimovich Узбекистан  
Дата: 16.09.11 19:33
Оценка:
Здравствуйте, k.o., Вы писали:

KO>Здравствуйте, Galiulin Rishat Faimovich, Вы писали:


GRF>>Здравствуйте, k.o., Вы писали:


KO>>>Здравствуйте, Galiulin Rishat Faimovich, Вы писали:


GRF>>>>Во многих языках есть поддержка со стороны языка IN, IN-OUT и OUT параметров, но в С++ такой нет вместо этого приходиться ипользовать константные и неконстантные ссылки и/или указатели. Поэтому я со своими коллегами решили что лучше было бы их раработать самим. В результате получилась такая реализация, но мы в ней не совсем уверены и хотели бы узнать мнение сообщества:


KO>>>Бессмысленный и беспощадный overdesign, который, к тому же, не всегда работает:


KO>>>
KO>>>class A
KO>>>{
KO>>>};

KO>>>void sink1(std::unique_ptr<const A> arg)
KO>>>{
KO>>>}

KO>>>void sink2(in<std::unique_ptr<const A>> arg)
KO>>>{
KO>>>}

KO>>>int main()
KO>>>{
KO>>>  std::unique_ptr<A> p1(new A);

KO>>>  sink1(std::move(p1)); // ok

KO>>>  std::unique_ptr<A> p2(new A);

KO>>>  sink2(in<std::unique_ptr<const A>>(std::move(p2))); // error
KO>>>}
KO>>>


GRF>>В нашей нотации необходимо несколько изменить вызов и определение:


KO>И получить другое поведение? Нет уж, так не пойдёт, боюсь, небольшим изменением тут не отделаться.


Нет вы получите именно то поведение которое желаете, попробуйте.

KO>>>и не всегда применим:


KO>>>
KO>>>MyType z = in<MyType&>(in<MyType&>(a) + in<MyType&>(in<MyType&>(b) * in<MyType&>(c)));
KO>>>


KO>>>во что это превратится с использованием expression templates я даже думать не хочу, впрочем, как я понял, некоторым такой вариант кажется более читабельным по сравнению с


KO>>>
KO>>>MyType z = a + b * c;
KO>>>


GRF>>Мы и не планировали что in, in_out и out будут так применяться .


KO>А как же ещё им применяться? Входные параметры есть, почему их не надо помечать? Впрочем, я, кажется, понимаю: благодаря удачным названиям функций способ использования передаваемых параметров очевиден, может, тогда, вместо изобретения велосипедов, стоит давать более удачные названия функциям?


Например в определении функции так:
void function( in< MyType& > a, in< MyType& > b, in< MyType& > c )
{
   MyType z = a() + b() * c();
}


Для того чтобы писать:
MyType z = a + b * c;

надо будет перегрузить операторы.
Re[5]: Реализация IN, IN-OUT и OUT параметров функций
От: k.o. Россия  
Дата: 16.09.11 20:07
Оценка:
Здравствуйте, Galiulin Rishat Faimovich, Вы писали:

GRF>>>В нашей нотации необходимо несколько изменить вызов и определение:


KO>>И получить другое поведение? Нет уж, так не пойдёт, боюсь, небольшим изменением тут не отделаться.


GRF>Нет вы получите именно то поведение которое желаете, попробуйте.


Но позвольте, конструкторы класса 'in' принимают константную ссылку на значение аргумента, мне же нужно передавать аргумент по-значению, для unique_ptr передача по константной ссылке и передача по значению это две большие разницы. Впрочем, я попробовал, как и ожидалось, "эквивалентный" код успешно компилируется, там где оригинальный (как и задумывалось) приводит к ошибке компиляции.

KO>>>>и не всегда применим:


KO>>>>
KO>>>>MyType z = in<MyType&>(in<MyType&>(a) + in<MyType&>(in<MyType&>(b) * in<MyType&>(c)));
KO>>>>


KO>>>>во что это превратится с использованием expression templates я даже думать не хочу, впрочем, как я понял, некоторым такой вариант кажется более читабельным по сравнению с


GRF>>>Мы и не планировали что in, in_out и out будут так применяться .


KO>>А как же ещё им применяться? Входные параметры есть, почему их не надо помечать? Впрочем, я, кажется, понимаю: благодаря удачным названиям функций способ использования передаваемых параметров очевиден, может, тогда, вместо изобретения велосипедов, стоит давать более удачные названия функциям?


GRF>Например в определении функции так:

GRF>
GRF>void function( in< MyType& > a, in< MyType& > b, in< MyType& > c )
GRF>{
GRF>   MyType z = a() + b() * c();
GRF>}
GRF>


MyType operator+( in< MyType& > lhs, in< MyType& > rhs )
{
    return ...;
}


что я делаю не так?

GRF>Для того чтобы писать:

GRF>
GRF>MyType z = a + b * c;
GRF>

GRF>надо будет перегрузить операторы.

ну да, надо будет, это вы к чему сказали?
Re[6]: Реализация IN, IN-OUT и OUT параметров функций
От: Galiulin Rishat Faimovich Узбекистан  
Дата: 16.09.11 20:51
Оценка:
Здравствуйте, k.o., Вы писали:

KO>Здравствуйте, Galiulin Rishat Faimovich, Вы писали:


GRF>>>>В нашей нотации необходимо несколько изменить вызов и определение:


KO>>>И получить другое поведение? Нет уж, так не пойдёт, боюсь, небольшим изменением тут не отделаться.


GRF>>Нет вы получите именно то поведение которое желаете, попробуйте.


KO>Но позвольте, конструкторы класса 'in' принимают константную ссылку на значение аргумента, мне же нужно передавать аргумент по-значению, для unique_ptr передача по константной ссылке и передача по значению это две большие разницы. Впрочем, я попробовал, как и ожидалось, "эквивалентный" код успешно компилируется, там где оригинальный (как и задумывалось) приводит к ошибке компиляции.


KO>>>>>и не всегда применим:


KO>>>>>
KO>>>>>MyType z = in<MyType&>(in<MyType&>(a) + in<MyType&>(in<MyType&>(b) * in<MyType&>(c)));
KO>>>>>


KO>>>>>во что это превратится с использованием expression templates я даже думать не хочу, впрочем, как я понял, некоторым такой вариант кажется более читабельным по сравнению с


GRF>>>>Мы и не планировали что in, in_out и out будут так применяться .


KO>>>А как же ещё им применяться? Входные параметры есть, почему их не надо помечать? Впрочем, я, кажется, понимаю: благодаря удачным названиям функций способ использования передаваемых параметров очевиден, может, тогда, вместо изобретения велосипедов, стоит давать более удачные названия функциям?


GRF>>Например в определении функции так:

GRF>>
GRF>>void function( in< MyType& > a, in< MyType& > b, in< MyType& > c )
GRF>>{
GRF>>   MyType z = a() + b() * c();
GRF>>}
GRF>>


KO>
KO>MyType operator+( in< MyType& > lhs, in< MyType& > rhs )
KO>{
KO>    return ...;
KO>}
KO>


KO>что я делаю не так?


GRF>>Для того чтобы писать:

GRF>>
GRF>>MyType z = a + b * c;
GRF>>

GRF>>надо будет перегрузить операторы.

KO>ну да, надо будет, это вы к чему сказали?


Спасибо Вам большое за помощь.

Вот новый вариант specification.hpp:
#ifndef SPECIFICATION_HPP
#   define SPECIFICATION_HPP

#   if 1 // in< class Type > - Functions input parameter
/**
 * @brief Functions input parameter
 * @tparam Type none reference input parameter type
 */
template< class Type >
class in
{
public:
    /**
     * Initialization constructor
     * @param value input parameter value
     */
    explicit in( const Type& value ): value_( value ) {}

    /**
     * Cast operator
     * @return input parameter value
     */
    operator const Type&() const
    {
        return value_;
    }

    /**
     * Gets parameter value
     * @return input parameter value
     */
    const Type& operator ()() const
    {
        return value_;
    }

private:
    template< class OtherType >
    in( const OtherType& value ); // disable implicit conversion for none reference objects

    /**
     * input parameter value
     */
    const Type& value_;
};

/**
 * @brief Functions input parameter
 * @tparam Type reference input parameter type
 */
template< class Type >
class in< Type& >
{
public:
    /**
     * Initialization constructor
     * @param value input parameter value
     */
    explicit in( const Type& value ): value_( value ) {}

    /**
     * Cast operator
     * @return input parameter value
     */
    operator const Type&() const
    {
        return value_;
    }

    /**
     * Gets parameter value
     * @return input parameter value
     */
    const Type& operator ()() const
    {
        return value_;
    }

private:
    /**
     * input parameter value
     */
    const Type& value_;
};

/**
 * @brief Functions input parameter
 * @tparam Type pointer input parameter type
 */
template< class Type >
class in< Type* >
{
public:
    /**
     * Initialization constructor
     * @param value input parameter value
     */
    explicit in( const Type* const value ): value_( value ) {}

    /**
     * Cast operator
     * @return input parameter value
     */
    operator const Type*() const
    {
        return value_;
    }

    /**
     * Gets parameter value
     * @return input parameter value
     */
    const Type* operator ()() const
    {
        return value_;
    }

    /**
     * Member selection by pointer operator
     * @return input parameter value
     */
    const Type* operator ->() const
    {
        return value_;
    }

private:
    /**
     * input parameter value
     */
    const Type* const value_;
};
#   endif

#   if 1 // in_out< class Type& > - Functions input-output parameter
/**
 * @brief Functions input-output parameter
 * @tparam Type none pointer input-output parameter type
 */
template< class Type >
class in_out
{
public:
    /**
     * Initialization constructor
     * @param value input-output parameter value
     */
    explicit in_out( Type& value ): value_( value ) {}

    /**
     * Cast operator
     * @return input-output parameter value
     */
    operator Type&() const
    {
        return value_;
    }

    /**
     * Gets parameter value
     * @return input-output parameter value
     */
    Type& operator ()() const
    {
        return value_;
    }

    /**
     * Assignment operator
     * @param value         assignment value
     * @tparam ValueType    assignment value type
     * @return input-output parameter value
     */
    template< class ValueType >
    Type& operator =( const ValueType& value )
    {
        return value_ = value;
    }

private:
    /**
     * input-output parameter value
     */
    Type& value_;
};

/**
 * @brief Functions input-output parameter
 * @tparam Type pointer input-output parameter type
 */
template< class Type >
class in_out< Type* >
{
public:
    /**
     * Initialization constructor
     * @param value input-output parameter value
     */
    explicit in_out( Type* & value ): value_( value ) {}

    /**
     * Cast operator
     * @return input-output parameter value
     */
    operator Type* &() const
    {
        return value_;
    }

    /**
     * Gets parameter value
     * @return input-output parameter value
     */
    Type* & operator ()() const
    {
        return value_;
    }

    /**
     * Assignment operator
     * @param value         assignment value
     * @tparam ValueType    assignment value type
     * @return input-output parameter value
     */
    Type* & operator =( Type* value )
    {
        return value_ = value;
    }

    /**
     * Member selection by pointer operator
     * @return input-output parameter value
     */
    Type* operator ->() const
    {
        return value_;
    }

private:
    /**
     * input-output parameter value
     */
    Type* & value_;
};
#   endif

#   if 1 // out< class Type* > - Functions output parameter
/**
 * @brief Functions output parameter
 * @tparam Type none pointer output parameter type
 */
template< class Type >
class out
{
public:
    /**
     * Initialization constructor
     * @param value output parameter value
     */
    explicit out( Type& value ): value_( value ) {}

    /**
     * Cast operator
     * @return output parameter value
     */
    operator Type&() const
    {
        return value_;
    }

    /**
     * Gets parameter value
     * @return output parameter value
     */
    Type& operator ()() const
    {
        return value_;
    }

    /**
     * Assignment operator
     * @param value         assignment value
     * @tparam ValueType    assignment value type
     * @return output parameter value
     */
    template< class ValueType >
    Type& operator =( const ValueType& value )
    {
        return value_ = value;
    }

    /**
     * Checks if parameter reference is null
     * @return <code>true</code> if parameter is null reference and <code>false</code> if parameter has reference
     */
    bool is_null()
    {
        return (&value_) == NULL;
    }

    /**
     * Creates null reference
     * @return null reference object
     */
    static Type& null()
    {
        return *reinterpret_cast< Type* >( NULL );
    }

private:
    /**
     * output parameter value
     */
    Type& value_;
};

/**
 * @brief Functions output parameter
 * @tparam Type pointer output parameter type
 */
template< class Type >
class out< Type* >
{
public:
    /**
     * Initialization constructor
     * @param value output parameter value
     */
    explicit out( Type* & value ): value_( value ) {}

    /**
     * Cast operator
     * @return output parameter value
     */
    operator Type* &() const
    {
        return value_;
    }

    /**
     * Gets parameter value
     * @return output parameter value
     */
    Type* & operator ()() const
    {
        return value_;
    }

    /**
     * Assignment operator
     * @param value         assignment value
     * @tparam ValueType    assignment value type
     * @return output parameter value
     */
    Type* & operator =( Type* value )
    {
        return value_ = value;
    }

    /**
     * Member selection by pointer operator
     * @return output parameter value
     */
    Type* operator ->() const
    {
        return value_;
    }

    /**
     * Checks if parameter reference is null
     * @return <code>true</code> if parameter is null reference and <code>false</code> if parameter has reference
     */
    bool is_null()
    {
        return (&value_) == NULL;
    }

    /**
     * Creates null reference
     * @return null reference object
     */
    static Type* & null()
    {
        return *reinterpret_cast< Type** >( NULL );
    }

private:
    /**
     * output parameter value
     */
    Type* & value_;
};
#   endif

/**
 * Ostream output operator
 * @param os            output stream
 * @param output        output value
 * @return output stream
 * @tparam CharType     @a os character type
 * @tparam OutputType   @a output type
 */
template< class CharType, class OutputType >
std::basic_ostream< CharType >& operator <<( in_out< std::basic_ostream< CharType > > os, const OutputType& output )
{
    return os() << output;
}

#endif /* SPECIFICATION_HPP */


Я имел ввиду что надо будет добавить операторы в specification.hpp .

Чтобы заработал Ваш пример оператора надо написать так:
MyType operator+( in< MyType& > lhs, in< MyType& > rhs )
{
    return lhs() + rhs();
}
Re[6]: Реализация IN, IN-OUT и OUT параметров функций
От: Galiulin Rishat Faimovich Узбекистан  
Дата: 16.09.11 21:07
Оценка:
Здравствуйте, k.o., Вы писали:

KO>Здравствуйте, Galiulin Rishat Faimovich, Вы писали:


GRF>>>>В нашей нотации необходимо несколько изменить вызов и определение:


KO>>>И получить другое поведение? Нет уж, так не пойдёт, боюсь, небольшим изменением тут не отделаться.


GRF>>Нет вы получите именно то поведение которое желаете, попробуйте.


KO>Но позвольте, конструкторы класса 'in' принимают константную ссылку на значение аргумента, мне же нужно передавать аргумент по-значению, для unique_ptr передача по константной ссылке и передача по значению это две большие разницы. Впрочем, я попробовал, как и ожидалось, "эквивалентный" код успешно компилируется, там где оригинальный (как и задумывалось) приводит к ошибке компиляции.


KO>>>>>и не всегда применим:


KO>>>>>
KO>>>>>MyType z = in<MyType&>(in<MyType&>(a) + in<MyType&>(in<MyType&>(b) * in<MyType&>(c)));
KO>>>>>


KO>>>>>во что это превратится с использованием expression templates я даже думать не хочу, впрочем, как я понял, некоторым такой вариант кажется более читабельным по сравнению с


GRF>>>>Мы и не планировали что in, in_out и out будут так применяться .


KO>>>А как же ещё им применяться? Входные параметры есть, почему их не надо помечать? Впрочем, я, кажется, понимаю: благодаря удачным названиям функций способ использования передаваемых параметров очевиден, может, тогда, вместо изобретения велосипедов, стоит давать более удачные названия функциям?


GRF>>Например в определении функции так:

GRF>>
GRF>>void function( in< MyType& > a, in< MyType& > b, in< MyType& > c )
GRF>>{
GRF>>   MyType z = a() + b() * c();
GRF>>}
GRF>>


KO>
KO>MyType operator+( in< MyType& > lhs, in< MyType& > rhs )
KO>{
KO>    return ...;
KO>}
KO>


KO>что я делаю не так?


GRF>>Для того чтобы писать:

GRF>>
GRF>>MyType z = a + b * c;
GRF>>

GRF>>надо будет перегрузить операторы.

KO>ну да, надо будет, это вы к чему сказали?


Извините кажется новый код тоже не работает, надо подумать.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.