Кресты / Говнокод #22689 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
using System;

public interface IFoo
{
    void WhoAmI<T>(T t);
}

public class Foo : IFoo
{
    public void WhoAmI<T>(T t)
    {
        Console.WriteLine(t.GetType().FullName);
    }
}

class pituh
{
    public static int Main(string[] args)
    {
        var f = new Foo() as IFoo;
        f.WhoAmI("asd");
        f.WhoAmI(10);
        return 0;
    }
}

Решите задачку.

есть некий код на C#

using System;

public interface IFoo
{
    void WhoAmI<T>(T t);
}

public class Foo : IFoo
{
    public void WhoAmI<T>(T t)
    {
        Console.WriteLine(t.GetType().FullName);
    }
}

class pituh
{
    public static int Main(string[] args)
    {
        var f = new Foo() as IFoo;
        f.WhoAmI("asd");
        f.WhoAmI(10);
        return 0;
    }
}


напишите его эквивалент на С++

Запостил: ASD_77 ASD_77, (Updated )

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

    • не. я давно не читал правила как "манглить" их. тем более что у gcc &msvc свои правила.
      Ответить
      • Для gcc/clang есть abi::__cxa_demangle. Думаю, что мелкомягкие тоже что-то выдумали (явно не как у людей).
        Иными словами, парочка #if с проверкой на компилятор/окружение должны решить вопрос c кросс-компиляторным demangle. Я почти уверен, что на GitHub (or whatever) уже можно найти рабочий код.

        P.S. abi::__cxa_demangle дико бесит, что не constexpr. А ведь тип вполне себе известен на этапе компиляции. Такое ограничение не дает делать constexpr там, где надо получить имя типа...
        Ответить
          • Тоже нет. Хотя имена типов можно вполне себе вкомпилить в бинарник как и остальные строки. Да, не всех, а только нужных.

            Оператор, который генерирует литерал по имени типа. Что-то вида typeid.
            template <typename T>
            void foo() {
                printf("%s\n", type_str(T));
            }
            Ответить
            • Можно для него даже слово typename зареюзать, чтобы новый кейворд не вводить.
              Ответить
  • #include <system>
    
    class IFoo
    {
    public:
        virtual void WhoAmI(void* t) = 0;
    };
    
    class Foo : public IFoo
    {
    public:
        void WhoAmI(void* t)
        {
            Console.WriteLine("void*");
        }
    };
    
    int main() {
        IFoo *f = new Foo;
        f.WhoAmI((void*)"asd");
        f.WhoAmI((void*)10);
        return 0;
    }


    а ты часом не бароп?
    Ответить
    • вы сознательно ушли тут от темплейта. а в этом суть вопроса 🙂
      Ответить
      • Это шуточка была. А если серьезно, то в плюсах аналогичное реализуемо с помощью boost::any и boost::demangle. И на сколько я понимаю, в сисярпе под копотом оно работает как раз примерно так.
        Ответить
        • в сисяпре оно работает как есть. т.к. виртуальная таблица хранит указатель на дженерик метод который переводиться в специализацию во время выполнения кода. а значит никакого кастинга делать не приходиться из-за того что используется тип генерика
          Ответить
          • А в C++ вообще на этапе компиляции известно, какая конкретная реализация шаблона выполняется, и поэтому тем более не приходится ничего ни к чему кастовать.
            Ответить
            • А особо умный конпелятор вообще весь этот код выкинет и заменит на вывод нужных строк...
              Ответить
              • а нука раскажи мне милый чел как это компилятор опеределит какая функция была вызванна особенно если она "virtual" что бы ее выкинуть :).
                Ответить
                • Да запросто, если создание объекта неподалёку находится (а оно тут как раз в соседней строчке с вызовом). Девиртуализацию никто не отменял.
                  Ответить
                  • ну в принципе да. но если прогнать через функцию тогда у компилятора облом будет, но он изначально скажет что виртуальные теплейтные функции идут в лес 🙂
                    Ответить
                    • > виртуальные теплейтные функции идут в лес
                      И правильно сделает.
                      Ответить
                  • # Девиртуализацию никто не отменял.

                    Что бы отменить что то, надо решить что то.
                    Ответить
                • Программа отрабатывает за конечное малое время, её результат постоянен и может быть вычислен на этапе компиляции. Теоретических ограничений нет.
                  Ответить
                  • не важно сколько оно проведет время ее результат определить не возможно т.к. у компилятора нет метода определить какой класс является владельцем интерфейса(ака абстрактного класа) а значит "задача оптимизации" результата не имеет и оптимизация прозведенна не может быть. кроме одного случая о котором написал bormand
                    Ответить
                    • Указанный код работает за небольшой промежуток времени, результат его выполнения не изменяется от запуска к запуску и может быть легко вычислен ещё на стадии написания программы. Нельзя доказать отсутствие компилятора, который проведёт эту оптимизацию.
                      Ответить
                      • >> Нельзя доказать отсутствие компилятора, который проведёт эту оптимизацию.

                        ну так скомпиляйте нам код. а мы посмотрим на него 🙂
                        Ответить
                        • Мой конпелятор из C# в C# вот что выдал:
                          class main
                          {
                              public static int Main(string[] args)
                              {
                                  System.Console.WriteLine("System.String");
                                  System.Console.WriteLine("System.Int32");
                                  return 0;
                              }
                          }
                          Ответить
            • Собсно в этом и разница шаблона и генерика.
              Ибо генерик вообще не шаблон, это сахарок над Foo<Object>.
              В крестах же напротив, шаблонный метод виртуальным не сделать.
              Ответить
              • Асд77 выше утверждает, что там не касты в рантайме, а инстанцирование шаблонного метода в рантайме (типа сисярп в рантайме конпелирует конкретную реализацию, как jit). Это если я правильно его понял. Сам-то я не знаю и гуглить не хочу.
                Ответить
                • пусть тогда сделает статический полиморфизм в шарпике в виде перегрузки
                  int f(Collection<Integer> c) { return 1; }
                  int f(Collection<String> c) { return 2; }

                  раз две принципиально различные вещи для него должны быть сравнимы в категориях лучше-хуже
                  Ответить
                  • using System;
                    
                    namespace Rextester
                    {
                        public class Collection<T> {};
                        
                        public class Program
                        {
                            static int f(Collection<int> c) { return 1; }
                            static int f(Collection<string> c) { return 2; }
                            
                            public static void Main(string[] args)
                            {                      
                                //Your code goes here
                                Console.WriteLine(f((Collection<int>)null));
                                Console.WriteLine(f((Collection<string>)null));
                            }
                        }
                    }


                    на балуйся.

                    1
                    2
                    Ответить
                    • ок, спасибо, почитал про разницу в генериках java vs c#

                      ну тогда другой пример - template specialization:
                      int f<T>(T c) { return 1; }
                      int f<>(string c) { return 2; }  // c# не может в <>, на стековерфлоу советуют их убрать и получить просто перегрузку
                      
                      int g<T>(T c) { return f(c); }
                      
                      call g((string)null);


                      если кококомпилятор c# сохраняет информацию о типах, и сам по себе язык обмазан сахаром в 10 слоев, что им помешало реализовать такую несложную вещь, как частичная/полная специализация?

                      ну или аналог крестушкового template <int N, int M> class Matrix()

                      раз уж так хочется сравнить несравнимое
                      интересно послушать
                      Ответить
            • это бред - не говорят не люди не коты.

              там виртуальная функция для особо одаренных стоит что бы компелятор от с++ жидко обгадился когда начнет применять темплейты к фиртуальной функции
              Ответить
              • > метод который переводиться
                > делать не приходиться
                > это бред - не говорят не люди не коты.
                > что бы компелятор
                > там виртуальная функция для особо одаренных стоит что бы компелятор от с++ жидко обгадился когда начнет применять темплейты к фиртуальной функции
                Да это же вореционный бот, который своим кобенаторным алгоритмом осознал C++ до возможности написания своего буста, но русский язык учил по комментариям на Ютубе.
                Ответить
    • красивый пример, но там IFoo темплейт. А хотелось бы безтемплейтный интерфейс (абстрактный класс)

      похоже надо самому строить __vtbl и вызывать через номер метода типа __vtbl[0]
      Ответить
      • А если оставить шаблону статику, но вывести значение общего типа и пустить его в динамику?
        class IFoo {
        public:
            template <typename T>
            void WhoAmI(const T &t) const {
                WhoAmI(typeid(t));
            }
        protected:
            virtual void WhoAmI(const std::type_info&) const = 0;
        };
        
        class Foo : public IFoo {
        public:
            virtual void WhoAmI(const std::type_info&) const {
                // ...
            }
        };

        А если WhoAmI(const std::type_info&) захочет распечатать само значение, дать ему ссылку на IPrinter, которую создавать в WhoAmI(const T &t), пока тип и значение известны.
        class IPrinter {
        public:
            virtual void print() const = 0;
        };
        
        template <typename T>
        class Printer : public IPrinter {
        public:
            Printer(const T& data) : data(data) {}
            virtual void print() const {
                std::cout << data;
            }
        private:
            const T& data;
        };
        Ответить
          • Хороший подход, виртуальные методы лучше "прятать". Так больше контроля над тем, что делают дочерние классы.
            Ответить
            • особенно над теми, которые виртуальные методы в паблик выносят
              Ответить
              • Вынос базового приватного (да, они нормально работают и в "private") виртуального метода в public -- личная психологическая проблема автора дочернего класса.
                Ответить
                • я бы не сказал, что изнасилование детей - проблема насильника
                  Ответить
          • а зачем вообще через виртуальные методы и наследование? оО
            Ответить
            • ASD_77 этого зачем-то хотел:
              там виртуальная функция для особо одаренных стоит что бы компелятор от с++ жидко обгадился когда начнет применять темплейты к фиртуальной функции

              Может, специально придумывал искусственную задачу, где C++ напрямую не работает как C#.
              Ответить
              • хз, можно в хэдер вынести всего лишь:
                struct TypeName {
                    template <typename T>
                    static void whoAmI(T &&) { _impl(typeid(T)); }
                private:
                    static void _impl(const std::type_info &);
                };

                а остальное в цппшник. И не надо инстанцировать никакой хуеты
                Ответить
              • ну да. в этом же и есть "задача" что бы обойти ограничение. Задача что бы мозги потренировать
                Ответить
      • Ламер, что ты там строить собрался? Я тебе уже написал про boost::any и boost::core::demangle.
        Ответить
          • ты уж если не знаешь, то и не пезди. any - это не просто войд*, а войд* + тайпинфо.
            Ответить
            • ок т.к. все абьюзят typeinfo в с++

              напишите код который будет работать
              using System;
              
              namespace Rextester
              {
                  public interface ICreator
                  {
                      T New<T>() where T : new();
                  }
                  
                  public class Foo : ICreator
                  {
                      public T New<T>() where T : new()
                      {
                          ////Console.WriteLine(typeof(T).Name);
                          return new T();
                      }
                  }
                  
                  public class Program
                  {
                      public static void Run(ICreator creator)
                      {
                          var newString = creator.New<Foo>();
                          var newpituh = creator.New<Program>();            
                      }
                      
                      public static void Main(string[] args)
                      {
                          Run(new Foo());
                      }
                  }
              }


              Да можеш заюзать Boost::any 🙂
              Ответить
              • Ламер, нельзя в плюсах функции в рантайме компилировать, хватит уже. И не нужно. В рантайме динамический полиморфизм, а шаблоны - в компайлтайме.
                Ответить
                • свали в тюбик - раз программить не научился. Во первых 1) никто не заставляет компилить в ++ это раз. во вторых с# написанн та тех же с++/c и прекрасно все умеет делать
                  Ответить
              • фабричный шаблонный метод, возвращающий инстанс класса? Ты, похоже, особая снежинка:
                template <typename T, typename ... Args>
                T *make(Args && ...args) {
                    return new T(std::forward<Args>(args)...);
                }
                Ответить
                • Прикол в том, что он хочет это делать через интерфейс. Т.е. совокупить единорога и лепрекона virtual и template в одном методе. Ясно, что в плюсах это (по крайней мере в стандарте) это невозможно.

                  С другой стороны сделать то, что он хочет, довольно просто с помощью паттерна из моего первого примера (aka "curiously recurring template pattern")
                  Ответить
                  • > по крайней мере в стандарте
                    Если учесть, что темплейт разворачивается (инстанциируется) только компилятором, и в рантайме инстанциированный темплейт это полноценный обособленный тип (или полноценная обособленная функция), которому в целом поебать, был ли он шаблонным когда-то, и кто его собратья и есть ли они вообще, при этом нет смысла хранить (мета?) код исходного темплейта - рантайму ничего с этим кодом не сделать, он не может и не должен в jit компиляцию какую-то, и новый код из xml или из сети он не сгенерит на лету (и тем более не прооптимизирует, не разберется со SFINAE, не найдет частичные специализации и т.д.) - то виртуальный шаблонный метод это оксюморон. Независимо от стандарта.

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

                    Буквально недавно я генерил различные многомерные данные (статистика), которые беком должны были обернуться в 0-мерные (значение), 1-мерные (массив), 2-мерные (массив массивов), 3-мерные (...) структуры и отправиться на фронт для визуализации.

                    Что сделал жавоёб? Один тип для T, второй тип для List<T>, третий тип для List<List<T>>, четвертый для List<List<List<T>>>.
                    Помогли ему его интерфейсы с виртуальными генериками? Хуй там.
                    Ответить
                    • а ниче что когда компилятор компилить темлейт то он становиться конкретной специализацией. А если он стал специализацией то уже перестал быть темлейтом а значить "virtual" должен аплаиться. А компилятор не знает как 🙂
                      Ответить
                      • куда-куда аплаиться?
                        виртуальный означает, что потомок будет переопределять когда-нибудь с тем же контрактом (имя+параметры)
                        это когда-нибудь может возникнуть в другой длл спустя 10 лет
                        базовый класс не может предугадать как потомок будет инстанциировать этот метод
                        что он может сохранить для потомка в данном случае?

                        только исходный код или AST или ещё какой-нибудь питух-байт-ллвм-код, и в таблице виртуальных методов эти самие питух-коды вообще в отдельные места складывать, т.к. это не исполняемые точки входа
                        и все потомки, переопределяющие этот шаблон своим таким же шаблоном, должны заменять родительский питух-байткод своим

                        чтобы когда-нибудь jit компилятор смог в рантайме проинстанциировать эту метушню в валидные исполняемые инструкции

                        ну или смириться с тем, что <T> это просто сраный сахарок над Object, и контракт этой виртуальной функции именно что принимаем/возвращаем Object, ну или void * - и в этом случае вообще никаких оптимизаций (код предка уже скомпилирован в бинарном виде и неизменяем) и тем более специализаций, максимум, проверки компилятора о типе возвращенного объекта (ещё один сахарок)
                        Ответить
                        • почему копмилятор не подумал что референсить методы в таблице можно не только через целое положительное число. А например по кол-ву параметров или по sha256 от имени метода?
                          Ответить
                          • По какому количеству?
                            Я всё ещё не пойму

                            Каждый шаблонный метод в крестах раскрывается в свою имплементацию сразу, как только компилятор видит необходимость в этом.
                            https://wandbox.org/permlink/N9ysRa2YhsT0d2SH
                            Затем все эти инстанциированные методы лягут в obj файл каждый под своим именем и адресом, чтобы линкер смог их в других модулях подставить в случае нужды.
                            Нет нужды в инстансе от, например, <char> - никто никакой код не сгенерит, и даже не подумает.

                            А в пределах единицы компиляции они вообще, скорее всего, заинлайнятся - тебе ведь обычно всё равно, являются ли они обособленными точками входа с каким то колл-конвеншеном, если тебе ни адреса не надо хранить, ничего, главное, чтобы они сделали "при вызове" то, что требуется. При инлайне компилятор их тело встроит в вызываемой код, перетасует, смешает с другими инструкциями, выкинет что-нибудь, и забудет, что это был шаблон какой-то какого-то класса foo, всё как обычно (для шарпера звучит диковато, понимаю).

                            Что именно ты собрался положить в ТВМ? Исходник шаблонного метода? Я об этом выше написал.

                            Т.к. спустя 10 лет я пишу свой тип MyAwesomeClass и инстанциирую им эту функцию, написанную кем-то 10 лет назад - какой код должен сгенерить компилятор за 10 лет до того, чтобы так заработало и потомком была найдена точка входа в подпрограмму foo::process<MyAwesomeClass>()?
                            Ответить
                            • давайте по порядку с самого начала.

                              1) проблема - С++ не разрешает использовать виртуальные темплейтные методы. Почему? потому что компилятор не может предугадать какие параметры темлейты могу быть использованны и поэтому не может сгенерировать __vtbl соответсвенно. А почему он не может это сделать? Ответ: потому что __vtbl распологает методы по порядку 0, 1, 2 в зависимости от того что в декларации класса написанно.

                              Но все это можно было бы избежать если бы методы в __vtbl референсились не по порядку как в декларации написанно а например по Hash code от имени функции, И тогда больше бы не было проблем с виртуальными темплейтными методами потому что "derived" класс всегда бы знал куда нужно положить метод в виртуальную таблицу.

                              т.е. не референсить по имени как делают dynamic языки а по hash - и все бы были довольны
                              Ответить
                              • Ты почитал что я написал выше?

                                virtual void process<int> и virtual void process<double> это две разные подпрограммы.
                                У них у каждой свои точки входа, у них у каждой свое тело, они даже вправе делать абсолютно своё, независимое друг от друга, и знать друг о друге не хотят.

                                При этом никакой точки входа у virtual void process<T> нет, т.к. в принципе нет никакого исполняемого кода, который олицетворял собой "неинстанциированный шаблон". Нет никаких машинных инструкций, не сохраняется никакого интермидиед-результата (там компилятор максимум AST может построить в процессе первого этапа разбора, проверить синтаксис - и то старые вижуал студии хуй забивали на двухэтапный разбор шаблона, проверяли только второй этап, в момент подстановки конкретного типа). В единице выполнения (exe, dll) шаблона нет. Есть только инстансы с конкретными типами. Всё. У них нет никакой семейственности. В исполняемой программе в режиме release нет никакого реестра созданных ей типов, ничего такого. Всё байты, даже небо, даже аллах. Исполняемый код - машинные инструкции под конкретную архитектуру/ОС/процессор.

                                В _vtbl должны лечь указатели на подпрограммы в качестве значения куда делать call/jmp.
                                Для метода process<T> никакого указателя нет. Для инстансов методов process<int> и process<double> свои указатели. Что класть в __vtbl? Какой из них может переопределить потомок? Что будет, если потомок захочет третий вариант инстанциированного шаблона? Какого объема рантайм нужно притащить в исполняемую единицу, чтобы имея исходный код шаблона (и всего, от чего он зависит) на лету сформировать ещё один метод, не хуже тех двух скомпилированных и прооптимизированных в процессе сборки? Кто будет заниматься поиском адресов функций, которые могут быть вызваны из такого генерирующегося метода в зависимости от текущего Т? А если там тоже шаблонные функции?
                                Ответить
                                • а ну да. так и есть. В этом и .опа что вызвать темлейт из виртуала нельзя. Но я больше думал про ситуацию когда все специализации темплейта уже известны. Но вот если юзать как либу и надо вызвать новую специализацию. Тогда без JITа никуда
                                  Ответить
                                • с# generic не template поэтому он не может кастить T в другой тип если не знает какие значения может получать T

                                  //Rextester.Program.Main is the entry point for your code. Don't change it.
                                  //Compiler version 4.0.30319.17929 for Microsoft (R) .NET Framework 4.5
                                  
                                  using System;
                                  using System.Collections.Generic;
                                  
                                  namespace Rextester
                                  {
                                      public class base1 { };
                                  
                                      public class class1 : base1 { };
                                  
                                      public class class2 : base1 { };
                                  
                                      public class Program
                                      {
                                          static int f<T>(T c) where T : base1 { return g(c); }
                                  
                                          static int g(base1 c)
                                          {
                                              switch (c)
                                              {
                                                  case class1 c1: return g(c1);
                                                  case class2 c2: return g(c2);
                                              }
                                  
                                              return 0;
                                          }
                                  
                                          static int g(class1 c) { return 1; }
                                          static int g(class2 c) { return 2; }
                                  
                                          public static void Main(string[] args)
                                          {
                                              //Your code goes here
                                              Console.WriteLine(f((class1)null));
                                              Console.WriteLine(f((class2)null));
                                          }
                                      }
                                  }


                                  вот ближайшая имплементация которая может работать
                                  Ответить
                                  • > с# generic не template
                                    ну наконец-то, спасибо!

                                    > он не может кастить T в другой тип
                                    Темплейт ничего не кастит.
                                    Он использует переданное точное значение типа вместо Т по всему своему коду для того, чтобы скомпилировать (не исполнить!) самостоятельный тип/функцию/метод, со всеми вытекающими (поэтому будет работать и вызов правильной перегруженной функции, и все остальное. А вот исходного шаблона никакого не останется.

                                    У меня всё.
                                    Ответить
                                    • угу. Согласен. Значит так надо юзать JIT. libjit уже есть. Но возникает вопрос. Нахрена тогда что-то юзать типа libjit есть уже есть c# & java? Ответ просто - потому что охота реюзать код на С++ например CryEngine а код писать на C# а рантайм юзать на андройде 🙂
                                      Ответить
                                      • Ламер, на плюсах написаны килотонны говнокода без виртуальных шаблонов и джитов. Просто пойми, что эта твоя мокрописечка не нужна.
                                        Ответить
                                        • Осушил твою писечку пятиокисью фосфора, проверь.
                                          Ответить
                                        • <a href=http://cialis10mgprixenpharmacieenligne.com/>cialis 10mg cpr4 prix en pharmacie </a>
                                          <a href=" http://cialis10mgprixenpharmacieenligne.com/ ">cialis 10mg prix en pharmacie en ligne </a>
                                          Ответить
                                        • <a href=http://cialis20mgprixenpharmacierx.com/>tadalafil 20mg prix </a>
                                          <a href=" http://cialis20mgprixenpharmacierx.com/ ">cialis 20mg prix en pharmacie </a>
                                          Ответить
                                        • <a href=http://achetercialisenfrancesitefiable.com/>acheter cialis 20mg en france </a>
                                          <a href=" http://achetercialisenfrancesitefiable.com/ ">acheter cialis generique en france </a>
                                          Ответить
                                        • <a href=http://achetercialissansordonnanceenpharmacie.c om/>acheter du cialis en france sans ordonnance </a>
                                          <a href=" http://achetercialissansordonnanceenpharmacie.c om/ ">vente de cialis sans ordonnance en france </a>
                                          Ответить
                                        • <a href=http://achatcialisenfrancelivraisonrapide.com>a chat cialis en france livraison rapide </a>
                                          <a href=" http://achatcialisenfrancelivraisonrapide.com ">acheter du cialis en ligne en france </a>
                                          Ответить
                                        • <a href=http://achatcialis5mgenligne.com/>achat cialis 5mg en ligne </a>
                                          <a href=" http://achatcialis5mgenligne.com/ ">acheter cialis 5mg en ligne en france </a>
                                          Ответить
                                        • <a href=http://tadalafil20mgpaschereninde.com/>cialis tadalafil 20mg pas cher </a>
                                          <a href=" http://tadalafil20mgpaschereninde.com/ ">tadalafil 20mg pas cher en inde </a>
                                          Ответить
                                        • <a href=http://achetertadalafilsansordonnance.com/>acheter tadalafil sans ordonnance </a>
                                          <a href=" http://achetertadalafilsansordonnance.com/ ">peut on acheter du cialis sans ordonnance en france </a>
                                          Ответить
                                        • <a href=http://achattadalafilenfranceenpharmacie.com/>acheter cialis en france </a>
                                          <a href=" http://achattadalafilenfranceenpharmacie.com/ ">achat cialis en ligne france </a>
                                          Ответить
                                        • <a href=http://acheterprednisone20mgenligne.com/>acheter prednisone </a>
                                          <a href=" http://acheterprednisone20mgenligne.com/ ">acheter prednisone 20 mg en ligne </a>
                                          Ответить
                                        • <a href=http://acheterpropeciasurinternet.com/>acheter du propecia sur internet </a>
                                          <a href=" http://acheterpropeciasurinternet.com/ ">acheter propecia sur internet </a>
                                          Ответить
                                        • <a href=http://achatamoxicillinebiogaran1g.com/>achat amoxicilline biogaran 1g </a>
                                          <a href=" http://achatamoxicillinebiogaran1g.com/ ">acheter amoxicilline 1g en ligne </a>
                                          Ответить
                        • > это когда-нибудь может возникнуть в другой длл спустя 10 лет
                          А если 10 лет назад кто-то скомпилирует указанный ниже класс, у нас при вызове A().method(Class2017()) будут проблемы?
                          class A {
                              template <typename T> void method(T) {}
                          };

                          Если будут, то это по сути та же ситуация, но только она допустима в C++, а значит спокойно можно было за счёт знания исходного кода в vtable нагенерить вореций для всех случаев.
                          Ответить
                      • можно явно инстанцировать шаблонных наследников базового класса, переопределяющих его виртуальные методы, спору нет. И можно в виртуальную функцию передавать какой-нибудь typeid, чтобы эта виртуальная функция могла работать с информацией о типе. Но придется всего-навсего явно инстанцировать специализации шаблона, для каждого типа, ручками.

                        Если выносить информацию о типах в рантайм можно вообще много какой метушни натворить. Вот только делать каждый инт наследником Object'а и инстанцировать его в хипе - не самый производительный сценарий, вы не находите?

                        п.с. именно поэтому студия аж 15 гигов весит (если уже не больше)
                        Ответить

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

Где здесь C++, guest?!

    А не использовать ли нам bbcode?


    8