Re[8]: Реализация IN, IN-OUT и OUT параметров функций
От: Galiulin Rishat Faimovich Узбекистан  
Дата: 19.09.11 11:27
Оценка:
Здравствуйте, k.o., Вы писали:

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


GRF>>Вроде написал более рабочий вариант specification.hpp:


KO>Да, уже лучше, только у нас, по прежнему, не поддерживается преобразование unique_ptr<A> -> unique_ptr<const A>, можно, конечно, сделать его явно:


KO>
KO>std::unique_ptr< A > p2( new A );
KO>sink2( in< std::unique_ptr< const A > >( std::move( std::unique_ptr< const A >( std::move(p2) ) ) ) );
KO>


KO>Но, я надеюсь, никому не придет в голову сказать что этот ужас читать легче чем


KO>
KO>std::unique_ptr< A > p1( new A );
KO>sink1( std::move( p1 ) );
KO>


Да, действительно выглядит плохо . Но можно немного короче
std::unique_ptr< A > p2( new A );
sink2( in< std::unique_ptr< const A > >( std::unique_ptr< const A >( std::move( p2 ) ) ) );


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

#include <ostream>

#   if 1 // in< class Type > - Functions input parameter
/**
 * @brief Functions input parameter
 * @tparam Type none reference input parameter type
 */
template< class Type >
class in
{
    template< class InType > friend in< InType > in_( const InType value );
public:
    /**
     * 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:
    /**
     * Initialization constructor
     * @param value input parameter value
     */
    explicit in( const Type& value ): value_( value ) {}

    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& >
{
    template< class InType > friend in< InType > in_( const InType value );
public:
    /**
     * 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:
    /**
     * Initialization constructor
     * @param value input parameter value
     */
    explicit in( const Type& value ): value_( value ) {}

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

/**
 * @brief Functions input parameter
 * @tparam Type pointer input parameter type
 */
template< class Type >
class in< Type* >
{
    template< class InType > friend in< InType > in_( const InType value );
public:
    /**
     * 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:
    /**
     * Initialization constructor
     * @param value input parameter value
     */
    explicit in( const Type* const value ): value_( value ) {}

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

/**
 * Function call input parameter specifier
 * @param value input parameter value
 * @return  input parameter
 */
template< class Type >
in< Type > in_( const Type value )
{
    return in< Type >( value );
}

/**
 * Function call input parameter by reference specifier
 * @param value input parameter value
 * @return  input parameter
 */
template< class Type >
in< Type& > in_ref_( const Type& value )
{
    return in< Type& >( 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
{
    template< class InOutType > friend in_out< InOutType > in_out_( InOutType& value );
public:
    /**
     * 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:
    /**
     * Initialization constructor
     * @param value input-output parameter value
     */
    explicit in_out( Type& value ): value_( value ) {}

    /**
     * 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* >
{
    template< class InOutType > friend in_out< InOutType > in_out_( InOutType& value );
public:
    /**
     * 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:
    /**
     * Initialization constructor
     * @param value input-output parameter value
     */
    explicit in_out( Type* & value ): value_( value ) {}

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

/**
 * Function call input-output parameter specifier
 * @param value input-output parameter value
 * @return  input-output parameter
 */
template< class Type >
in_out< Type > in_out_( Type& value )
{
    return in_out< 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
{
    template< class OutType > friend out< OutType > out_( OutType& value );
public:
    /**
     * 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:
    /**
     * Initialization constructor
     * @param value output parameter value
     */
    explicit out( Type& value ): value_( value ) {}

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

/**
 * @brief Functions output parameter
 * @tparam Type pointer output parameter type
 */
template< class Type >
class out< Type* >
{
    template< class OutType > friend out< OutType > out_( OutType& value );
public:
    /**
     * 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:
    /**
     * Initialization constructor
     * @param value output parameter value
     */
    explicit out( Type* & value ): value_( value ) {}

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

/**
 * Function call output parameter specifier
 * @param value output parameter value
 * @return  output parameter
 */
template< class Type >
out< Type > out_( Type& value )
{
    return out< 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 */


C ним нужно писать так:
std::unique_ptr< A > p2( new A );
sink2( in_( std::unique_ptr< const A >( std::move( p2 ) ) ) );



KO>Кроме того, у этого подхода есть ещё, скажем так, концептуальная проблема, из-за того что некоторые способы передачи параметров не укладываются в in, in_out и out. Например, мы хотим передавать владение unique_ptr дальше по цепочке вызовов:


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


А где здесь проблема? Можете подробнее? У меня вроде вот этот код работает
void sink( in< std::unique_ptr< const A > > arg)
{
}

void sink1( in< std::unique_ptr< const A > > arg)
{
  sink( std::move( arg ) );
}



KO>После этого можно будет вспомнить о существовании rvalue-references и необходимости поддерживать perfect forwarding.


При реализации мы к сожалению не ориетировались на новый стандарт С++
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.