Реализация IN, IN-OUT и OUT параметров функций
От: Galiulin Rishat Faimovich Узбекистан  
Дата: 13.09.11 14:41
Оценка: 3 (2) -2 :))) :)
Во многих языках есть поддержка со стороны языка IN, IN-OUT и OUT параметров, но в С++ такой нет вместо этого приходиться ипользовать константные и неконстантные ссылки и/или указатели. Поэтому я со своими коллегами решили что лучше было бы их раработать самим. В результате получилась такая реализация, но мы в ней не совсем уверены и хотели бы узнать мнение сообщества:

specification.hpp:
#ifndef SPECIFICATION_HPP
#   define SPECIFICATION_HPP

#   include <ostream>

/**
 * @brief Functions input parameter
 */
#   define IN
/**
 * @brief Functions input/output parameter
 */
#   define IN_OUT
/**
 * @brief Functions output parameter
 */
#   define OUT

#   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 is used
     * @return <code>true</code> if parameter has been set and <code>false</code> otherwise
     */
    bool used()
    {
        return ( &value_ ) != NULL;
    }

    /**
     * Checks if parameter is not used
     * @return <code>true</code> if parameter has not been set and <code>false</code> otherwise
     */
    bool not_used()
    {
        return !used();
    }

    /**
     * Creates unused parameter indicator
     * @return unused parameter indicator
     */
    static out unused()
    {
        return out( *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 is used
     * @return <code>true</code> if parameter has been set and <code>false</code> otherwise
     */
    bool used()
    {
        return ( &value_ ) != NULL;
    }

    /**
     * Checks if parameter is not used
     * @return <code>true</code> if parameter has not been set and <code>false</code> otherwise
     */
    bool not_used()
    {
        return !used();
    }

    /**
     * Creates unused parameter indicator
     * @return unused parameter indicator
     */
    static out unused()
    {
        return out( *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 */


А вот сравнение использования обычного и с применением in, in_out и out параметров:

main.cpp:
#include <string>
#include <iostream>
#include <stdio.h>

#include "specification.hpp"

class Base
{
public:
    virtual void print() const
    {
        std::cout << "Base" << std::endl;
    }
    virtual void operator()() const
    {
        std::cout << "Base::operator()" << std::endl;
    };
};

class Derived: public Base
{
public:
    virtual void print() const
    {
        std::cout << "Derived" << std::endl;
    }
    virtual void operator()() const
    {
        std::cout << "Derived::operator()" << std::endl;
    };
};

void function_0( const Base& paramIn )
{
    paramIn.print();
    paramIn();
}

void function_0( in< Base& > paramIn )
{
    paramIn().print();
    paramIn()();
}

void function_1( const std::string* const paramIn, int& paramInOut )
{
    printf( "%s\n", paramIn->c_str() );
    paramInOut = 21;
    printf( "%i\n", paramInOut );
    paramInOut += 34;
    printf( "%i\n", paramInOut );
}

void function_1( in< std::string* > paramIn, in_out< int > paramInOut )
{
    printf( "%s\n", paramIn->c_str() );
    paramInOut = 21;
    printf( "%i\n", paramInOut() );
    paramInOut += 34;
    printf( "%i\n", paramInOut() );
}

void function_2( const short paramIn, std::string* & paramInOut )
{
    std::string::size_type( std::string::* pCStr )() const = &std::string::size;
    paramInOut = new std::string();
    printf( "%u\n", ( paramInOut->*pCStr )() );
    printf( "%i\n", paramIn );
    printf( "%s\n", paramInOut->c_str() );
}

void function_2( in< short > paramIn, in_out< std::string* > paramInOut )
{
    std::string::size_type( std::string::* pCStr )() const = &std::string::size;
    paramInOut = new std::string();
    printf( "%u\n", ( paramInOut->*pCStr )() );
    printf( "%i\n", paramIn() );
    printf( "%s\n", paramInOut->c_str() ); ;
}

void function_3( const short* const paramIn, int* & paramInOut, int* * const paramOut = NULL )
{
    printf( "%i\n", paramIn[1] );
    if ( paramOut )
    {
        ( *paramOut )++;
    }
    paramInOut += 21;
    printf( "%i\n", *paramInOut++ );
    paramInOut += 34;
    printf( "%p\n", paramInOut );
}

void function_3( in< short* > paramIn, in_out< int* > paramInOut, out< int* > paramOut = out< int* >::unused() )
{
    printf( "%i\n", paramIn[1] );
    if ( paramOut.used() )
    {
        paramOut++;
    }
    paramInOut += 21;
    printf( "%i\n", *paramInOut++ );
    paramInOut += 34;
    printf( "%p\n", paramInOut() );
}

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 ) );
}
in in out out параметры функций
Re: Реализация IN, IN-OUT и OUT параметров функций
От: MasterZiv СССР  
Дата: 13.09.11 16:14
Оценка:
On 13.09.2011 18:41, Galiulin Rishat Faimovich wrote:
> IN, IN-OUT и OUT

IN есть,
IN-OUT есть,
OUT нет
Posted via RSDN NNTP Server 2.1 beta
Re: Реализация IN, IN-OUT и OUT параметров функций
От: MasterZiv СССР  
Дата: 13.09.11 16:18
Оценка:
On 13.09.2011 18:41, Galiulin Rishat Faimovich wrote:

> Во многих языках есть поддержка со стороны языка IN, IN-OUT и OUT параметров, но

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

А какой цели вы пытались достигнуть ?
Что в результате стало лучше в коде с использованием ваших IN, IN-OUT и OUT ?
Posted via RSDN NNTP Server 2.1 beta
Re[2]: Реализация IN, IN-OUT и OUT параметров функций
От: Galiulin Rishat Faimovich Узбекистан  
Дата: 13.09.11 17:17
Оценка:
Здравствуйте, MasterZiv, Вы писали:

MZ>On 13.09.2011 18:41, Galiulin Rishat Faimovich wrote:


>> Во многих языках есть поддержка со стороны языка IN, IN-OUT и OUT параметров, но

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

MZ>А какой цели вы пытались достигнуть ?

MZ>Что в результате стало лучше в коде с использованием ваших IN, IN-OUT и OUT ?

Спасибо за заинтересованность.
Хотели добиться повышения читабельности кода как для разработчика функции так и для пользователя.
А так же как следствие уменьшение количества ошибок.

В результате вместо ожидаемого малого overhead получили даже некоторую оптимизацию на компиляторах
icc и gcc, на cl к сожалению этот overhead появился (мы сравнивали сгенерированные ассемблерные
инструкции для release версий тестов)
Re[2]: Реализация IN, IN-OUT и OUT параметров функций
От: Galiulin Rishat Faimovich Узбекистан  
Дата: 13.09.11 17:20
Оценка:
Здравствуйте, MasterZiv, Вы писали:

MZ>On 13.09.2011 18:41, Galiulin Rishat Faimovich wrote:

>> IN, IN-OUT и OUT

MZ>IN есть,

MZ>IN-OUT есть,
MZ>OUT нет

Я не совсем понял, что ви имели ввиду. Можете написать подробнее?
Re: Реализация IN, IN-OUT и OUT параметров функций
От: alexeiz  
Дата: 13.09.11 17:48
Оценка:
Здравствуйте, Galiulin Rishat Faimovich, Вы писали:

GRF>
GRF>    function_1( in< std::string* >( &InString ), in_out< int >( InOutInteger ) );
GRF>    function_2( in< short >( InShort ), in_out< std::string* >( pInOutString ) );
GRF>    function_3( in< short* >( &InShort ), in_out< int* >( pInOutInteger ) , out< int* >( pInOutInteger ) );
GRF>


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

У меня было так, когда я хотел такое изобрести (но потом выбросил за ненадобностью):

string_to_int(in|str, out|n);
Re[2]: Реализация IN, IN-OUT и OUT параметров функций
От: Galiulin Rishat Faimovich Узбекистан  
Дата: 13.09.11 18:17
Оценка:
Здравствуйте, alexeiz, Вы писали:

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


GRF>>
GRF>>    function_1( in< std::string* >( &InString ), in_out< int >( InOutInteger ) );
GRF>>    function_2( in< short >( InShort ), in_out< std::string* >( pInOutString ) );
GRF>>    function_3( in< short* >( &InShort ), in_out< int* >( pInOutInteger ) , out< int* >( pInOutInteger ) );
GRF>>


A>Типы параметров нужно указывать при вызове функций? Выглядит очень некрасиво, и писать гораздо больше без особой причины.


A>У меня было так, когда я хотел такое изобрести (но потом выбросил за ненадобностью):


A>
A>string_to_int(in|str, out|n);
A>


Спасибо за пост.
Да согласен что писать надо больше и что выглядит не совсем так хотелось бы. Но есть и плюсы — код читабельнее.
А это в свою очередь как я с коллегами ожидаем уменьшит количество ошибок и облегчит дальнейшую поддержку.
Второй плюс — это то улучшает оптимизацию кода на icc и на gcc, к сожалению есть небольшой overhead на cl
Re[3]: Реализация IN, IN-OUT и OUT параметров функций
От: uzhas Ниоткуда  
Дата: 13.09.11 19:18
Оценка: +1
Здравствуйте, Galiulin Rishat Faimovich, Вы писали:

GRF>А это в свою очередь как я с коллегами ожидаем уменьшит количество ошибок и облегчит дальнейшую поддержку.

я вам могу порекомендовать отказаться от out\inout параметров и тогда ваши проблемы исчезнут сами собой
Re[4]: Реализация IN, IN-OUT и OUT параметров функций
От: rumit7  
Дата: 13.09.11 19:58
Оценка:
Здравствуйте, uzhas, Вы писали:

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


GRF>>А это в свою очередь как я с коллегами ожидаем уменьшит количество ошибок и облегчит дальнейшую поддержку.

U>я вам могу порекомендовать отказаться от out\inout параметров и тогда ваши проблемы исчезнут сами собой

Цитата из "Совершенный код" С.Макконнелла:

"В данном примере ключевые слова-макросы IN и OUT используются для документирования. Чтобы значение параметра можно было изменить в вызванном методе, параметр все же нужно передавать по указателю или по ссылке.

Прежде чем принять этот подход, обдумайте два его важных недостатка. Собственные ключевые слова IN и OUT окажутся незнакомыми большинству программистов, которые будут читать ваш код. Расширяя язык таким образом, делайте это согласованно, лучше всего в масштабе всего проекта. Второй недостаток в том,
что компилятор не будет проверять соответствие параметров ключевым словам IN и OUT, из-за чего вы сможете отметить параметр как IN и все же изменить его внутри метода. Так вы только введете программиста, читающего ваш код, в заблуждение."

На мой взгляд именно эта цитата хорошо отражает намерения автора, а именно:

1) для улучшения читабельности кода;
2) чтобы дать дополнительные гарантии изменяемости/не изменяемости OUT/IN параметров соответственно.
Re[4]: Реализация IN, IN-OUT и OUT параметров функций
От: Galiulin Rishat Faimovich Узбекистан  
Дата: 14.09.11 05:53
Оценка:
Здравствуйте, uzhas, Вы писали:

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


GRF>>А это в свою очередь как я с коллегами ожидаем уменьшит количество ошибок и облегчит дальнейшую поддержку.

U>я вам могу порекомендовать отказаться от out\inout параметров и тогда ваши проблемы исчезнут сами собой

Спасибо за совет.
Re[3]: Реализация IN, IN-OUT и OUT параметров функций
От: MasterZiv СССР  
Дата: 14.09.11 08:13
Оценка:
On 13.09.2011 21:17, Galiulin Rishat Faimovich wrote:

> Хотели добиться повышения читабельности кода как для разработчика функции так и

> для пользователя.

Для этого достаточно тупо писать комментарии или пустые макросы IN, IN_OUT и OUT
перед параметрами. Для примера см. реализацию современного WinAPI.
Posted via RSDN NNTP Server 2.1 beta
Re[3]: Реализация IN, IN-OUT и OUT параметров функций
От: MasterZiv СССР  
Дата: 14.09.11 08:23
Оценка:
On 13.09.2011 21:20, Galiulin Rishat Faimovich wrote:

> MZ>IN есть,

> MZ>IN-OUT есть,
> MZ>OUT нет
>
> Я не совсем понял, что ви имели ввиду. Можете написать подробнее?

Что языком поддерживаются эти парадигмы передачи параметров.
(одна не поддерживается, ещё не поддерживается передача по имени)
Posted via RSDN NNTP Server 2.1 beta
Re[3]: Реализация IN, IN-OUT и OUT параметров функций
От: MasterZiv СССР  
Дата: 14.09.11 08:24
Оценка:
On 13.09.2011 21:17, Galiulin Rishat Faimovich wrote:

> В результате вместо ожидаемого малого overhead получили даже некоторую

> оптимизацию на компиляторах

При передаче болших структур по значению ? Раньше вы по значению
передавали, теперь по константной ссылке ?
Posted via RSDN NNTP Server 2.1 beta
Re: Реализация IN, IN-OUT и OUT параметров функций
От: Аноним  
Дата: 14.09.11 08:45
Оценка: +1
Здравствуйте, Galiulin Rishat Faimovich, Вы писали:

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


GRF>
GRF>int main( int argc, char **argv )
GRF>{
GPF>    //поскипано
GRF>    function_3( in< short* >( &InShort ), in_out< int* >( pInOutInteger ) , out< int* >( pInOutInteger ) );
GRF>}
GRF>


И вот это по вашему легче читаемо?
Не, ну этож песец на ровном месте такие огороды городить.
Re[4]: Реализация IN, IN-OUT и OUT параметров функций
От: Аноним  
Дата: 14.09.11 09:33
Оценка:
Здравствуйте, MasterZiv, Вы писали:

MZ>On 13.09.2011 21:17, Galiulin Rishat Faimovich wrote:


>> В результате вместо ожидаемого малого overhead получили даже некоторую

>> оптимизацию на компиляторах

MZ>При передаче болших структур по значению ? Раньше вы по значению

MZ>передавали, теперь по константной ссылке ?

Нет не при передаче больших структур а именно при передаче по ссылке или указателю.
Думаю шаблоны дают компилятору какую-то дополнительную информацию о типе и по этой пирине он убирает излишние проверки.
Re[4]: Реализация IN, IN-OUT и OUT параметров функций
От: Аноним  
Дата: 14.09.11 09:45
Оценка:
Здравствуйте, MasterZiv, Вы писали:

MZ>On 13.09.2011 21:17, Galiulin Rishat Faimovich wrote:


>> Хотели добиться повышения читабельности кода как для разработчика функции так и

>> для пользователя.

MZ>Для этого достаточно тупо писать комментарии или пустые макросы IN, IN_OUT и OUT

MZ>перед параметрами. Для примера см. реализацию современного WinAPI.

Как вы можете заметить у нас так же имеются эти define-ы и мы их использовали.
Проблема была в том что можно было по ошибке написать не то определене перед параметром и
компилятор при этом не выдавал сообщений об ошибке. Шаблонная же реализация обеспечивает жесткую
связь как между определением параметра и его ипользованием, так и между определением функции и ее вызовом.
Re[2]: Реализация IN, IN-OUT и OUT параметров функций
От: Galiulin Rishat Faimovich Узбекистан  
Дата: 14.09.11 09:49
Оценка:
Здравствуйте, Аноним, Вы писали:

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


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


GRF>>
GRF>>int main( int argc, char **argv )
GRF>>{
GPF>>    //поскипано
GRF>>    function_3( in< short* >( &InShort ), in_out< int* >( pInOutInteger ) , out< int* >( pInOutInteger ) );
GRF>>}
GRF>>


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

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

Да, я думаю, что это достаточно читабельно. Даже без "поскипано"го кода примерно понятно что функция может сделать с параметрами.
Как плюс здесь еще производится проверка типов параметров.
Re[3]: Реализация IN, IN-OUT и OUT параметров функций
От: Аноним  
Дата: 14.09.11 10:47
Оценка:
Здравствуйте, Galiulin Rishat Faimovich, Вы писали:

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


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


GRF>Да, я думаю, что это достаточно читабельно. Даже без "поскипано"го кода примерно понятно что функция может сделать с параметрами.


Вы это серьёзно?
Ок, а если будет так:

void foo(IN int* bar_in, OUT char* bar_out, IN_OUT int* bar_in_out);


Разве читающему не будет понятен этот код?
Или он менее читаем чем приведённый вами?

GRF>Как плюс здесь еще производится проверка типов параметров.

Ага, только не как плюс...
Такое ощущение что ради этого всё и затевалось.
Re[4]: Реализация IN, IN-OUT и OUT параметров функций
От: Galiulin Rishat Faimovich Узбекистан  
Дата: 14.09.11 11:11
Оценка:
Здравствуйте, Аноним, Вы писали:

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


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


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


GRF>>Да, я думаю, что это достаточно читабельно. Даже без "поскипано"го кода примерно понятно что функция может сделать с параметрами.


А>Вы это серьёзно?

А>Ок, а если будет так:

А>
А>void foo(IN int* bar_in, OUT char* bar_out, IN_OUT int* bar_in_out);
А>


А>Разве читающему не будет понятен этот код?

А>Или он менее читаем чем приведённый вами?

GRF>>Как плюс здесь еще производится проверка типов параметров.

А>Ага, только не как плюс...
А>Такое ощущение что ради этого всё и затевалось.

Да вы правы иради этого тоже, я просто неправильно выразился
Re[4]: Реализация IN, IN-OUT и OUT параметров функций
От: Galiulin Rishat Faimovich Узбекистан  
Дата: 14.09.11 11:20
Оценка:
Здравствуйте, Аноним, Вы писали:

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


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


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


GRF>>Да, я думаю, что это достаточно читабельно. Даже без "поскипано"го кода примерно понятно что функция может сделать с параметрами.


А>Вы это серьёзно?

А>Ок, а если будет так:

А>
А>void foo(IN int* bar_in, OUT char* bar_out, IN_OUT int* bar_in_out);
А>


А>Разве читающему не будет понятен этот код?

А>Или он менее читаем чем приведённый вами?

GRF>>Как плюс здесь еще производится проверка типов параметров.

А>Ага, только не как плюс...
А>Такое ощущение что ради этого всё и затевалось.

Еще ваш пример я думаю лучше будет написать так:
void foo(IN const int* const bar_in, OUT char* bar_out, IN_OUT int& bar_in_out);

И для сравнения наш вариант:
void foo(in< int* > bar_in, out< char > bar_out, in_out< int > bar_in_out);
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.