Re[3]: Как избавиться от лишних аргументов
От: AleksandrN Россия  
Дата: 25.09.12 19:27
Оценка:
Здравствуйте, PlusMyTwitterFace, Вы писали:

К>>Если функция принимает указатель, то она, вроде бы, обязана проверять на ноль


PMT>Не хотелось бы на это просто рассчитывать.


А что про передачу NULL в качестве параметра этой функции говорит документация по библиотеке?
Re[3]: Как избавиться от лишних аргументов
От: Erop Россия  
Дата: 25.09.12 20:15
Оценка:
Здравствуйте, freestyle, Вы писали:

PD>>
PD>>struct PARAM
PD>>{
PD>>std::size_t _1;
PD>>float* _2;
PD>>double* _3;
PD>>int* _4;
PD>>};

PD>>void foo(PARAM* param);

PD>>// вызов

PD>>PARAM param;
PD>>memset(&param, 0, sizeof(PARAM);
PD>>// установи нужные поля. Остальные будут NULL.
PD>>foo(&param);

PD>>


F>NULL не всегда равен 0! Ваш код не переносим.


К сожалниею, переносимый код
PARAM param = PARAM();
// установи нужные поля. Остальные будут NULL.
foo(&param);
верно компилируется сильно не всеми компиляторами, так что, формально, прав, конечно же ты, а вот на практике, код Дворкина возможно таки и попереносимее может оказаться...
Хотя бываеют, конечно, контроллеры, в которых нулевой бинароно указатель вполне валиден
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re: Как избавиться от лишних аргументов
От: Erop Россия  
Дата: 25.09.12 20:18
Оценка:
Здравствуйте, PlusMyTwitterFace, Вы писали:

PMT>В C99 и C11 эту проблему можно решить при помощи compound literals:


PMT>В C++ на ум приходит лишь два решения:


А что за С++? 03 или можно 11?..
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re: Как избавиться от лишних аргументов
От: MasterZiv СССР  
Дата: 25.09.12 20:52
Оценка:
> Можно ли каким-то образом "избавиться" от "лишних" аргументов функции?

В бусте кстати есть библиотека поддержки именованных параметров.
Используется в boost::graph. Но саму библиотеку я забыл.
Можеш либо использовать, либо стянуть идею.
Posted via RSDN NNTP Server 2.1 beta
Re[4]: Как избавиться от лишних аргументов
От: freestyle  
Дата: 25.09.12 20:56
Оценка:
Здравствуйте, Erop, Вы писали:

F>>NULL не всегда равен 0! Ваш код не переносим.


E>К сожалниею, переносимый код
E>PARAM param = PARAM();
E>// установи нужные поля. Остальные будут NULL.
E>foo(&param);
верно компилируется сильно не всеми компиляторами, так что, формально, прав, конечно же ты, а вот на практике, код Дворкина возможно таки и попереносимее может оказаться...

E>Хотя бываеют, конечно, контроллеры, в которых нулевой бинароно указатель вполне валиден

Ваш вариант тоже не переносим (что бы стал переносим нужно написать свой конструктор "по умолчанию", но это уже другой разговор). Более того, он не корректен для С.
Re[5]: Как избавиться от лишних аргументов
От: Erop Россия  
Дата: 26.09.12 01:23
Оценка:
Здравствуйте, freestyle, Вы писали:

F>Ваш вариант тоже не переносим (что бы стал переносим нужно написать свой конструктор "по умолчанию", но это уже другой разговор).


Чушь, ботай value initialization.

F>Более того, он не корректен для С.

И что с того?

Да, вариант с агрегатом сбивает оптимизаторы. Например, оптимизатор MSVC...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[3]: Как избавиться от лишних аргументов
От: maykie Россия  
Дата: 26.09.12 03:02
Оценка:
Здравствуйте, PlusMyTwitterFace, Вы писали:

M>>Ну сделай несколько врапперов. Делов-то.


PMT>Как я уже сказал выше, данные функции принадлежат библиотеке.


Ну и? Пускай принадлежат.

M>>и?


PMT>А ничего, что таких врапперов мне придётся тогда написать, скажем, 200?


Ты намерен использовать все 200 врапперов? Если нет(а я уверен, что нет), то не пиши 200. Делов-то
Re[3]: Как избавиться от лишних аргументов
От: Pavel Dvorkin Россия  
Дата: 26.09.12 07:30
Оценка:
Здравствуйте, freestyle, Вы писали:

F>NULL не всегда равен 0! Ваш код не переносим.


Да, может быть такое. Если рассматривать основные платформы — вполне переносим.
With best regards
Pavel Dvorkin
Re[6]: Как избавиться от лишних аргументов
От: freestyle  
Дата: 26.09.12 11:00
Оценка: -1
Здравствуйте, Erop, Вы писали:

F>>Ваш вариант тоже не переносим (что бы стал переносим нужно написать свой конструктор "по умолчанию", но это уже другой разговор).


E>Чушь, ботай value initialization.


Сами сначала изучите "value initialization".

F>>Более того, он не корректен для С.

E>И что с того?

Ничего, все

E>Да, вариант с агрегатом сбивает оптимизаторы. Например, оптимизатор MSVC...


Никто здесь ничего не сбивает.
Re[3]: Как избавиться от лишних аргументов
От: PlusMyTwitterFace  
Дата: 26.09.12 19:42
Оценка:
Спасибо за совет, ознакомлюсь с Вашей реализацией.

Есть, правда, пара моментов:

— Здесь присутствует ошибка с порядком инициализации полей — deleter объявлен в классе раньше data, хотя инициализируется в списке инициализации конструктора позже.

— gcc 4.7.1 не компилирует assert'ы в данном коде. Пока не вникал в суть ошибок.
Re[4]: Как избавиться от лишних аргументов
От: Piko  
Дата: 26.09.12 19:48
Оценка: +1
Здравствуйте, PlusMyTwitterFace, Вы писали:

PMT>- Здесь присутствует ошибка с порядком инициализации полей — deleter объявлен в классе раньше data, хотя инициализируется в списке инициализации конструктора позже.


А кто тебе сказал что это ошибка? (порядок вызова от этого не меняется)
Re[4]: Как избавиться от лишних аргументов
От: Erop Россия  
Дата: 26.09.12 20:09
Оценка: :)
Здравствуйте, PlusMyTwitterFace, Вы писали:

PMT>- Здесь присутствует ошибка с порядком инициализации полей — deleter объявлен в классе раньше data, хотя инициализируется в списке инициализации конструктора позже.


не пофиг ли?

PMT>- gcc 4.7.1 не компилирует assert'ы в данном коде. Пока не вникал в суть ошибок.

#include <assert.h> типа...

Но уровень дискуссии доставляет. Ты правда не знаешь, что такое assert?..
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[5]: Как избавиться от лишних аргументов
От: PlusMyTwitterFace  
Дата: 26.09.12 20:21
Оценка: -1
E>не пофиг ли?

В данном случае всё равно.

E>Но уровень дискуссии доставляет. Ты правда не знаешь, что такое assert?..


Не понял. К чему этот вопрос и с чего он возник? Вы думаете, что я не в состоянии включить cassert / assert.h?

Ошибки, на самом деле, возникали в связи с -Wall -Werror, с которыми я запускал gcc, из-за всё того же порядка инициализации. Про assert показалось, просто рядом было.
Re[6]: Как избавиться от лишних аргументов
От: Erop Россия  
Дата: 26.09.12 20:29
Оценка:
Здравствуйте, PlusMyTwitterFace, Вы писали:

PMT>В данном случае всё равно.

PMT>Не понял. К чему этот вопрос и с чего он возник? Вы думаете, что я не в состоянии включить cassert / assert.h?

Ну раньше думал, что в состоянии, но теперь не уверен...

PMT>Ошибки, на самом деле, возникали в связи с -Wall -Werror, с которыми я запускал gcc, из-за всё того же порядка инициализации. Про assert показалось, просто рядом было.


На самом деле это был код, написанный для демонстрации концепции, он вообще не обязан компилироваться...
Но уровень дискуссии всё равно доставляет
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[4]: Как избавиться от лишних аргументов
От: Erop Россия  
Дата: 28.09.12 12:28
Оценка:
Здравствуйте, PlusMyTwitterFace, Вы писали:

PMT>Спасибо за совет, ознакомлюсь с Вашей реализацией.

PMT>Есть, правда, пара моментов:

Кстати, я добрался до компилятора, и проверил чего там и как, и нашёл ошибку.
у шаблона структуры CFakeArgument::CData не хватает специализации
    template<typename T> 
    struct CData<const T> : CData<T> {};


  то есть полностью должно быть так
class CFakeArgument {
    typedef double alignAs_t; // можно прагамами, С++11 или ещё как замутить, не суть.
    enum { bufSize = 32 }; // В общем сколько стеку не жаль
    
    struct CBuffer {
        alignAs_t alignPad;
        char bytes[bufSize - sizeof( alignAs_t )];
    } buffer;

    typedef  void deleter_t( void* );
    deleter_t* deleter;
    void* data;
    
    CFakeArgument( const CFakeArgument& ); // = delete
    void operator = ( const CFakeArgument& ); // = delete
    
    //    Полиморфная часть
    template<typename T> 
    struct CData {
        T Data;
        
        void* operator new( size_t size, CBuffer& dstBuffer )
        {
            if( sizeof( CData ) <= bufSize ) {
                assert( size <= bufSize );
                return &dstBuffer;
            } else {
                return ::new char[size];
            }
        }

        void operator delete( void* p, CBuffer& dstBuffer )
        {
            if( sizeof( CData ) <= bufSize ) {
                assert( p == 0 || p == &dstBuffer );
            } else {
                ::delete[] (char*)p;
            }
        }

        void operator delete( void* p )
        {
            if( sizeof( CData ) > bufSize ) {
                ::delete[] (char*)p;
            }
        }

        static void deleter( void* p )
        {
            delete static_cast<CData*>( p );
        }
        
        T& Save( void*& thisStorage, deleter_t*& deleterStorage )
        {
            assert( thisStorage == 0 && deleterStorage == 0 );
            thisStorage = this;
            deleterStorage = deleter;
            return Data;
        }
    };
    
    template<typename T> 
    struct CData<const T> : CData<T> {};


public:
    CFakeArgument() : deleter( 0 ), data( 0 ) {}; // По просьбам трудящихся ;)
    ~CFakeArgument() { if(deleter != 0 ) deleter( data ); }
    
    template<typename T>
    operator T&()
    {
        if( data == 0 ) {
            return ( new( buffer ) CData<T> )-> Save( data, deleter );
        } else {
            assert( deleter == CData<T>::deleter );
            return static_cast<CData<T>*>(data)->Data;
        }
    }
    template<typename T>
    operator T*() { return &(T&)(*this); }
};

#define _0_ CFakeArgument()

Прада, если делать это всё законченным решением, то нехило бы поддержать ещё и буфера.
Например, можно приписать operator[], которому в аргумент передаёют размер буфера, а он возвращает аналог или наследник CFakeArgument, который по operator T*() аллокирует буфер нужного размера. Правда всё раво не ясно, что делать с T**, которые обычно используются для того, что бы передать указатель на буфер, который будет аллокирован внутри функции и возвращён наружу, так как есть, как минимум два популярных способа его разрушения. Через free и через delete[]...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[2]: Как избавиться от лишних аргументов
От: Sni4ok  
Дата: 28.09.12 12:44
Оценка:
Здравствуйте, Константин, Вы писали:

К>Если функция принимает указатель, то она, вроде бы, обязана проверять на ноль.


чё за бред, по вашему и strlen на 0 проверяет?
Re[3]: Как избавиться от лишних аргументов
От: Erop Россия  
Дата: 28.09.12 13:41
Оценка:
Здравствуйте, Sni4ok, Вы писали:

S>чё за бред, по вашему и strlen на 0 проверяет?


Я думаю, что имелись в виду факультативные параметры...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re: Как избавиться от лишних аргументов
От: Erop Россия  
Дата: 29.09.12 08:38
Оценка:
Здравствуйте, PlusMyTwitterFace, Вы писали:

PMT>Можно ли каким-то образом "избавиться" от "лишних" аргументов функции?


<...>

PMT>Что посоветуете сделать?


http://users.livejournal.com/_winnie/229311.html -- тоже метод
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re: Как избавиться от лишних аргументов
От: DestinyChild  
Дата: 29.09.12 11:10
Оценка:
ндя.... прочитал все и так понял, что не удивительно, что у нас год от года все больше гигарец и гигабайт доступно, но проги все больше и больше тупят и тормозят...
уважаемый PlusMyTwitterFace: писать самое главное надо просто — и если вам что-то не нравиться в чем-то — это не повод изобретать велики и носки-самокаты с нуля. И все уважаемые советчики — нахрена в данной ситуации вы даже просто позволили себе подумать — А КАК эту задачу можно решать по другому? Нахрена городить уйму строк с шаблонами и черт-еще-знает-чем? Просто потому что С++ это позволяет — а вы решили что так можно написать?
Простейшая ситуация, когда надо задать только последний параметр в функции превратилась просто в монстра по решениям. Вам не страшно потом этот ужас поддерживать? Исправлять? Передавать, так сказать, по наследству кому-то?
Вот ответьте сперва на главнейший вопрос — нафига в вопросе, заданном PlusMyTwitterFace вообще искать какое-то новое решение?
Кто и главное КАК выиграет от нового решения? и в чем?
Re[2]: Как избавиться от лишних аргументов
От: Centaur Россия  
Дата: 29.09.12 13:18
Оценка: +1 :)
Здравствуйте, DestinyChild, Вы писали:

DC>нахрена в данной ситуации вы даже просто позволили себе подумать[…]?


Потому что можем.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.