1. C++ / Говнокод #12713

    +14

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    struct base {
       template <class Foo>
    	base() {}
    };
    
    struct derived {
    	derived()
    		: base::base<int>()		// why not?? WHHYYYY?
    	{}
    };
    
    base b1 = base::base<int>();
    base b2<int>();

    долбанный комитет
    им проще запретить, чем продумать нормальный способ вызова шаблонного конструктора

    Запостил: defecate-plusplus, 09 Марта 2013

    Комментарии (13) RSS

    • ну и отступы у нашего уютного редактора...
      я всегда буду нажимать предпросмотр
      я всегда буду нажимать предпросмотр
      я всегда буду нажимать предпросмотр
      Ответить
    • Кажется, у вас derived : public base отклеился
      Ответить
      • да, но суть ясна
        явно указать шаблонные параметры конструктора нет возможности, потому что by design невозможно вызвать конструктор
        так что придется передавать аргумент, например, boost::mpl::identity<>
        Ответить
    • > им проще запретить, чем продумать нормальный способ вызова шаблонного конструктора
      Все чего нет в крестах - не нужно.
      Ответить
    • Кстати, если не секрет, а что делает этот конструктор с переданным ему типом? Т.к. сама структура base не параметризована, в мою сонную голову приходят только sizeof(T) да new T или new Some<T>().
      Ответить
      • Если я владею телепатией, и правильно угадал зачем передавать тип в конструктор непараметризованного класса (а скорее всего я не угадал, и как обычно сморозил хуйню), то пропихнуть тип в конструктор можно как-то так:
        struct base {
            size_t size;
            void *data;
            template <class T> struct type {
                size_t size() const { return sizeof(T); }
                void *alloc() const { return new T(); }
            };
            template <class T> base(const base::type<T> &bt) {
                size = bt.size();
                data = bt.alloc();
            }
        };
        struct derived : public base {
            derived() : base(base::type<int>()) {}
        };
        Ответить
        • struct base {
              template <class T> class type {};
              template <class T> base(const base::type<T> &) {
                  // ... do something with T ...
              }
          };
          struct derived : public base {
              derived() : base(base::type<int>()) {}
          };
          Ответить
          • > так что придется передавать аргумент, например, boost::mpl::identity<>
            P.S. Я всегда буду читать комментарии и документацию по теме перед тем как писать всякую хуйню. Я только что почти запилил boost::mpl::identity<>, осталось только typedef T type добавить в мой base::type...
            Ответить
            • Кстати, еще в голову пришло решение без лишних типов и MPL:
              struct base {
                  template <class T> base(T *) {
                      // ... do anything with T ...
                  }
              };
              struct derived : public base {
                  derived() : base((int*)0) {}
                  derived() : base(static_cast<int*>(0)) {} // для с++наци
              };
              Ответить
        • да воркэраунд чтобы пропихнуть тип я уже выше написал - передать в конструктор неоверхедный объект, из которого этот самый тип будет выводиться компилятором
          например,
          template <class Foo>
          base(boost::mpl::identity<Foo>) {
             // use Foo here ...
          }
          
          base b1(boost::mpl::identity<int>());

          я сейчас пересматриваю идеологию нашей асинхронной вермишели, и вот в одном месте понадобилось 1) чтобы базовый класс на этапе конструктора владел информацией о типе своего реального потомка (чтобы вывести тип коллбека) и при этом 2) CRTP не подходит, т.к. нужен полиморфизм в пределах очереди базовых классов

          я еще пока не уверен в том, что получается, но и по старому мне тоже не нравится (каждый потомок после своего конструктора сейчас требует отдельного вызова set_completion_handler()), надоело тащить этот хвост, конструктор неплохое место, чтобы задать сразу все
          Ответить
          • и, быть может, про непригодность CRTP я несколько погорячился :)
            Ответить
          • > неоверхедный объект
            Да даже указатель сойдет, это я тупил сильно, и городил свои костыли ;)

            > CRTP не подходит
            А CRTP чем мешает полиморфизму? Просто добавить еще один промежуточный шаблонный класс между base и derived. Он и тип будет знать и полиморфизм не порушит.
            class base { };
            template <class T> struct base_for_crtp : public base {
                base_for_crtp() {
                    // use T here to call set_completition_handler
                    // or just pass it to the base constructor via T* or boost::mpl::identity<T>
                }
            };
            class derived : public base_for_crtp<derived> {
            };
            P.S. Хотя смотрится это страшнее ;(
            Ответить
    • vanished
      Ответить

    Добавить комментарий