
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[216.73.216.21] |
![]() |
|
Страницы: (78) « Первая ... 24 25 [26] 27 28 ... 77 78 ( Перейти к последнему сообщению ) |
Сообщ.
#376
,
|
|
|
Цитата Masterkent @ но комитет просто не видит в этом достаточной выгоды, чтобы переписывать правила. Странно (на мой взгляд). Достаточно взглянуть на приведенный пример. Ведь это просто следующий шаг (после лямбд и инстанцирования локальными типами). in-place-полиморфные врапперы, избавляющие кодера от, гм..., ненужных шаманств. Другой пример (по идее, должен компилироваться): ![]() ![]() class Foo { public: typedef boost::variant<int, std::string, double> var_type; void Process(var_type const& v) { struct Processor : boost::static_visitor<> { Foo* m_Object; Processor(Foo* obj) : m_Object(obj) {;} template<typename T> void operator()(T val) const {m_Object->Process(val);} } p(this); boost::apply_visitor(p, v); } private: void Process(int a); void Process(std::string a); void Process(double a); }; Теперь прикинь, сколько тебе придется писать сейчас. А учитывая, что этот Processor можно завернуть в макрос: ![]() ![]() #define DEF_VISITOR(cls, method) \ struct Processor : boost::static_visitor<> \ { \ cls* m_Object; \ Processor(cls* obj) : m_Object(obj) {;} \ template<typename T> void operator()(T val) const {m_Object->Method(val);} \ } с последующим использованием: ![]() ![]() class Foo { public: typedef boost::variant<int, std::string, double> var_type; void Process(var_type const& v) { DEF_VISTOR(Foo, Process) p(this); boost::apply_visitor(p, v); } private: void Process(int a); void Process(std::string a); void Process(double a); }; разница становится еще более очевидной. Добавлено Только что проверил (на полусобранном gcc 4.5) - локальный класс в теле метода класса имет полный доступ к private-потрохам класса. Что и требуется. |
![]() |
Сообщ.
#377
,
|
|
Цитата Flex Ferrum @ Ну, значениями тебе никто не запрещал пользоваться, перечисления-то не требуют квалификации именем своего типа, т.к. они не создают областей видимости. Но ведь речь-то шла не о значениях, а о типе. Значение параметром в typename T не передашь.Ну, вообще говоря, по-моему, отсутствие имени у таких перечислений не мешало мне использовать их в качестве параметров шаблонов... У них ведь, вроде как (у констант, в смысле) получается тип int. Или я чего-то недопонимаю? Проблема стала актуальной с появлением decltype и наделением auto новых возможностей. Их-то не запрещается использовать с безымянными типами. |
Сообщ.
#378
,
|
|
|
Flex Ferrum
когда gcc 4.5 обещают? |
Сообщ.
#379
,
|
|
|
Цитата Большой @ когда gcc 4.5 обещают? Я ожидаю не раньше марта следующего года (судя по датам выходов предыдущих релизов). Сейчас четвертый день пытаюсь его из исходников под MinGW сбилдить... ![]() ![]() ![]() ![]() |
Сообщ.
#380
,
|
|
|
Цитата Flex Ferrum @ Вообщем, как только получится - выложу здесь было бы очень хорошо |
Сообщ.
#381
,
|
|
|
Цитата Flex Ferrum @ Теперь прикинь, сколько тебе придется писать сейчас. Можно сделать Processor закрытым членом Foo. Цитата Flex Ferrum @ А учитывая, что этот Processor можно завернуть в макрос Тут, кстати, видна другая проблема: шаблонными аргументами нельзя передавать имена функций. Довольно неприятное ограничение. Указатели на функции-члены неудобны: ни с перегруженными функциями, ни с шаблонами функций, ни с функциями, имеющими аргументы по умолчанию, их зачастую нормально не поюзаешь. Иметь дело с именами функций было бы куда удобнее: ![]() ![]() // подобное использование virtual, .(Fn) и .. - это просто мои допущения, в C++0x ничего такого нет. template <virtual Fn, class C> class MemFnBinder { public: MemFnBinder(C const &x) : m_obj(x) {} template <class... Args> auto operator ()(Args &&... args) const -> decltype(m_obj.(Fn)(args...)) { return m_obj.(Fn)(args...); } private: C m_obj; }; template <virtual Fn, class C> MemFnBinder<Fn, C> bind(C const &x) { return MemFnBinder<Fn, C>(x); } struct X { void func(int, int = 0); }; void f() { std::function<void (int)> fn1 = bind<..func>(X()); std::function<void (int, int)> fn2 = bind<..func>(X()); } И, в частности, твой макрос можно было бы переписать примерно так: ![]() ![]() template <class C, virtual Fn> class Processor : boost::static_visitor<> { public: Processor(C* obj) : m_object(obj) {} template <class T> void operator()(T val) const { m_object->(Fn)(val); } private: C* m_object; } причём, по-моему, не было бы никакого смысла делать такой шаблон локальным. Если он настолько обобщённый, что используется сразу в нескольких местах, то, наверное, ему самое место в пространстве имён. Локальным имело бы смысл делать код, который нигде больше, кроме как в данной функции, не используется - например: ![]() ![]() template <class BidirectionalIterator> void reverse(BidirectionalIterator first, BidirectionalIterator last) { struct Aux { template <class BidirIt> void operator()(BidirIt first, BidirIt last, std::bidirectional_iterator_tag) { for (; first != last && first != --last; ++first) (swap)(*first, *last); } template <class RanIt> void operator ()(RanIt first, RanIt last, std::random_access_iterator_tag) { for (; first < last; ++first) (swap)(*first, *--last); } }; Aux()(first, last, typename std::iterator_traits<BidirectionalIterator>::iterator_category()); } |
Сообщ.
#382
,
|
|
|
Цитата Masterkent @ причём, по-моему, не было бы никакого смысла делать такой шаблон локальным. В таком случае - да. Но... ![]() Цитата Masterkent @ Можно сделать Processor закрытым членом Foo. Можно. Но это значит вносить изменения в интерфейс класса, что (в ряде случаев, да и вообще) некомильфо. А локальный класс (в данном случае) никуда, кроме функции (в которой объявлен) не "выглядывает". Цитата Masterkent @ Тут, кстати, видна другая проблема: шаблонными аргументами нельзя передавать имена функций. Довольно неприятное ограничение. Угумс. Именно эту проблему и есть желание обойти. Указанным мною образом. |
Сообщ.
#383
,
|
|
|
Цитата Flex Ferrum @ Но это значит вносить изменения в интерфейс класса Публичного интерфейса класса это почти не касается, поэтому проблема второсортная, IMHO. |
Сообщ.
#384
,
|
|
|
Цитата Masterkent @ Публичного интерфейса класса это почти не касается, поэтому проблема второсортная, IMHO. Зато приведет к перекомпиляции зависимого от интерфейса кода. А это уже хуже. |
Сообщ.
#385
,
|
|
|
Цитата Flex Ferrum @ Зато приведет к перекомпиляции зависимого от интерфейса кода. Если эта проблема критична, то можно поместить данный вспомогательный класс в unnamed namespace. |
Сообщ.
#386
,
|
|
|
Цитата Masterkent @ Если эта проблема критична, то можно поместить данный вспомогательный класс в unnamed namespace. Да много чего можно то. ![]() |
Сообщ.
#387
,
|
|
|
Цитата Flex Ferrum @ Да много чего можно то. О том и речь: есть масса неплохих workaround-ов, так что оснований для пересмотра правил здесь может быть недостаточно. |
Сообщ.
#388
,
|
|
|
Цитата Masterkent @ есть масса неплохих workaround-ов, так что оснований для пересмотра правил здесь может быть недостаточно. Но удочку закинуть все равно можно. |
Сообщ.
#389
,
|
|
|
В смысле, поинтересоваться мнением общественности по этому поводу где-нибудь в comp.std.c++ |
Сообщ.
#390
,
|
|
|