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();
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.