шаблоны С++ и дженерики С#
От: kochetkov.vladimir Россия https://kochetkov.github.io
Дата: 07.09.09 10:00
Оценка: 1 (1)
Пишу сюда, т.к. интересует мнение вменяемых апологетов сразу двух языков, чья концентрация превышает норму только здесь, в ФП.

В рамках участия в небольшом мирном холиварчике на внутрикорпоративном форуме на тему сабжа, мне выкатили пример использования шаблонов С++ для реализации "псевдо-наследования" в контексте "вот как ты это на шарпе с дженериками сделаешь?", как бы намекая на то, что в шарпе нельзя унаследовать дженерик от его же параметра-типа:

#include<iostream>

using namespace std;

template < class T > 
class Test : public T
{
    public:
        void Test1()
        {
            cout<<"Test1"<<endl;
        };
};

class Papa
{
    public:
        void Papa1()
        {
            cout<<"Papa1"<<endl;
        };
};

class Mama
{
    public:
        void Mama1()
        {
            cout<<"Mama1"<<endl;
        };
};

void main()
{
    Test<Papa> testPapa;
    testPapa.Papa1();
    testPapa.Test1();

    Test<Mama> testMama;
    testMama.Mama1();
    testMama.Test1();
}




в результате ковыряний в студии, я эмперически пришел вот к такому коду:

using System;

namespace Generics1
{
    class Test<T> where T : Test<T>, new()
    {
        public void Test1() {
            Console.WriteLine("Test1");
        }

        public T getInstance() {
            return new T();
        }
    }

    class Papa : Test<Papa>
    {
        public Papa() { }

        public void Papa1() {
            Console.WriteLine("Papa1");
        }
    }

    class Mama : Test<Mama>
    {
        public Mama() { }

        public void Mama1() {
            Console.WriteLine("Mama1");
        }
    }

    class Program
    {
        static void Main(string[] args) {
            var testPapa = new Test<Papa>().getInstance();
            testPapa.Test1();
            testPapa.Papa1();

            var testMama = new Test<Mama>().getInstance();
            testMama.Test1();
            testMama.Mama1();

            Console.ReadKey();
        }
    }
}


Собственно вопрос к местным гуру плюсов и шарпа : действительно ли приведенный шарповый код аналогичен плюсовому? Если нет, то в чем разница (кроме compile-time/runtime)?

И вопрос со звездочкой (я не знаю ответ): почему этот код вообще компилируется и тем более выполняется? (смущает, в основном, "class Test<T> where T : Test<T>")

[Интервью] .NET Security — это просто
Автор: kochetkov.vladimir
Дата: 07.11.17
Re: шаблоны С++ и дженерики С#
От: nikov США http://www.linkedin.com/in/nikov
Дата: 07.09.09 11:27
Оценка: 7 (1)
Здравствуйте, kochetkov.vladimir, Вы писали:

В C# действуют следующие правила:

10.1.4 Class base specification
A base class cannot be a type parameter on its own, though it can involve the type parameters that are in scope.

class Extend<V>: V {}            // Error, type parameter used as base class


10.1.5 Type parameter constraints
In either case, the constraint can involve any of the type parameters of the associated type or method declaration as part of a constructed type, and can involve the type being declared.

Re: шаблоны С++ и дженерики С#
От: 0x7be СССР  
Дата: 07.09.09 11:41
Оценка: +2
Здравствуйте, kochetkov.vladimir, Вы писали:


KV>Собственно вопрос к местным гуру плюсов и шарпа : действительно ли приведенный шарповый код аналогичен плюсовому? Если нет, то в чем разница (кроме compile-time/runtime)?


Как минимум есть такая разница: в плюсовом коде классы Pama & Mama "ничего не знают" о шаблоне Test, в то время
как в шарповой версии вносится зависимость.

Плюс еще то, что количество экземпляров Test<T> в шарповом коде больше: та, которая явно создается через new и та, которая создается как база класса Pama/Mama.

Насчёт легальности указанного ограничения — что не запрещено, то разрешено!
Re: шаблоны С++ и дженерики С#
От: jazzer Россия Skype: enerjazzer
Дата: 07.09.09 13:03
Оценка: 14 (1)
Здравствуйте, kochetkov.vladimir, Вы писали:

KV>Собственно вопрос к местным гуру плюсов и шарпа : действительно ли приведенный шарповый код аналогичен плюсовому? Если нет, то в чем разница (кроме compile-time/runtime)?


Нет, не аналогичен, он аналогичен трюку CRTP (Curiously Recurring Template Pattern), это немножко другое.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[2]: шаблоны С++ и дженерики С#
От: kochetkov.vladimir Россия https://kochetkov.github.io
Дата: 07.09.09 13:55
Оценка: 8 (1) :)
Здравствуйте, 0x7be, Вы писали:

0>Здравствуйте, kochetkov.vladimir, Вы писали:



KV>>Собственно вопрос к местным гуру плюсов и шарпа : действительно ли приведенный шарповый код аналогичен плюсовому? Если нет, то в чем разница (кроме compile-time/runtime)?


0>Как минимум есть такая разница: в плюсовом коде классы Pama & Mama "ничего не знают" о шаблоне Test, в то время

0>как в шарповой версии вносится зависимость.

В ответ на аналогичный аргумент, я отправил коллеге вот такой код:

using System;
using System.Collections.Generic;
using System.Reflection;

namespace Generics2
{
    public class MultipleInheritedObject
    {
        private Dictionary<Type, Object> _mixins = new Dictionary<Type, Object>();

        public MultipleInheritedObject(params Type[] mixins)
        {
            foreach (Type type in mixins)
                _mixins.Add(type, Activator.CreateInstance(type));
        }

        public Interface As<Interface>()
        {
            Object implementation;
            if (_mixins.TryGetValue(typeof(Interface), out implementation))
                return (Interface)implementation;
            throw new System.InvalidCastException();
        }
    }

    class Test : MultipleInheritedObject
    {
        public Test(params Type[] mixins) : base(mixins) { }

        public void Test1()
        {
            Console.WriteLine("Test1");
        }
    }

    class Papa
    {
        public Papa() { }

        public void Papa1()
        {
            Console.WriteLine("Papa1");
        }
    }

    class Mama
    {
        public Mama() { }

        public void Mama1()
        {
            Console.WriteLine("Mama1");
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var test = new Test(typeof(Papa), typeof(Mama));

            test.Test1();
            test.As<Papa>().Papa1();
            test.As<Mama>().Mama1();

            Console.ReadKey();
        }
    }
}


и никаких тебе зависимостей, почти...

[Интервью] .NET Security — это просто
Автор: kochetkov.vladimir
Дата: 07.11.17
Re[3]: шаблоны С++ и дженерики С#
От: jazzer Россия Skype: enerjazzer
Дата: 07.09.09 14:19
Оценка:
Здравствуйте, kochetkov.vladimir, Вы писали:

KV>В ответ на аналогичный аргумент, я отправил коллеге вот такой код:


Чем-то он мне неуловимо Python напоминает
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[3]: шаблоны С++ и дженерики С#
От: 0x7be СССР  
Дата: 07.09.09 15:57
Оценка: +1
Здравствуйте, kochetkov.vladimir, Вы писали:

KV>В ответ на аналогичный аргумент, я отправил коллеге вот такой код:

KV> ...
KV>и никаких тебе зависимостей, почти...
Ну, есть там к чему придраться, если честно. Но дело не в этом.
В чем главное различие дженериков и шаблонов, если не вдаваться в тонкости их реализации?
Различие состоит в том, что шаблоны обеспечивают "compile time duck typing", а дженерики — нет.
Отсюда и разница в их возможностях. При этом .NET обладаем всеми необходимыми компонентами, что бы смоделировать эту функциональность в том или ином виде. То, что Вы написали — один их возможных шагов к этому
Re: шаблоны С++ и дженерики С#
От: VladD2 Российская Империя www.nemerle.org
Дата: 08.09.09 19:20
Оценка: 11 (3) +2 -5
Здравствуйте, kochetkov.vladimir, Вы писали:

Скажу так. Это глупый спор.

Ни шаблоны, ни дженерики не являются панацеей. У каждого свои особенности которые одновременно порождают и плюсы и минусы.

Да, полноценного множественного наследования (МН) на дженериках не реализовать. Но так же точно на шаблонах нельзя реализовать даже что-то похожее на компонентность.

Правильный ответ на притязания С++-ников — в языках с дженериками надо использовать другие паттерны, другие подходы, другие идеомы. Однако С++-ники никогда не поймут этого, так как они мыслят паттернами характерными для С++, которые заучены ими за долгую (или не очень) практику программирования на этом языке.

Проблему МН можно было бы решить добавив в язык пару/тройку расширений. Например, миксины. То как это может выглядеть можно поглядеть в Scala. Там аналогичная возможность называется traits
Автор(ы): Билл Веннерс, Мартин Одерски, Лекс Спун
Дата: 30.07.2007
Scala – статически типизированный, объектно-ориентированный язык программирования, в котором смешиваются императивный и функциональный стили программирования. Одна из причин заинтересоваться программированием на Scala, состоит в том, что Scala позволяет увеличить производительность разработчика по сравнению с Java, сохраняя скорость исполнения JVM, существующие инвестиции в Java-код, знания и множество API, имеющихся для JVM. Scala обладает краткостью языков типа Ruby или Python, но при этом статически типизирована, как и Java.
. Это более узкое нежели МН решение, но оно отлично решает задачу добавления функционала к классу (и не создает при этом проблем). А именно эта задача обычно приводится сторонниками МН в качестве аргумента.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: шаблоны С++ и дженерики С#
От: Константин Б. Россия  
Дата: 10.09.09 10:33
Оценка:
Здравствуйте, kochetkov.vladimir, Вы писали:

KV>Пишу сюда, т.к. интересует мнение вменяемых апологетов сразу двух языков, чья концентрация превышает норму только здесь, в ФП.


KV>В рамках участия в небольшом мирном холиварчике на внутрикорпоративном форуме на тему сабжа, мне выкатили пример использования шаблонов С++ для реализации "псевдо-наследования" в контексте "вот как ты это на шарпе с дженериками сделаешь?", как бы намекая на то, что в шарпе нельзя унаследовать дженерик от его же параметра-типа:


А какая практическая польза от такого трюка?
Re[2]: шаблоны С++ и дженерики С#
От: kochetkov.vladimir Россия https://kochetkov.github.io
Дата: 10.09.09 13:17
Оценка:
Здравствуйте, Константин Б., Вы писали:

КБ>Здравствуйте, kochetkov.vladimir, Вы писали:


KV>>Пишу сюда, т.к. интересует мнение вменяемых апологетов сразу двух языков, чья концентрация превышает норму только здесь, в ФП.


KV>>В рамках участия в небольшом мирном холиварчике на внутрикорпоративном форуме на тему сабжа, мне выкатили пример использования шаблонов С++ для реализации "псевдо-наследования" в контексте "вот как ты это на шарпе с дженериками сделаешь?", как бы намекая на то, что в шарпе нельзя унаследовать дженерик от его же параметра-типа:


КБ>А какая практическая польза от такого трюка?


А я хз, какая По мне, так необходимость в этом трюке говорит о проблемах с дизайном Но рассуждать об этом в контексте сравнения плюсов и шарпа было как-то неинтересно

[Интервью] .NET Security — это просто
Автор: kochetkov.vladimir
Дата: 07.11.17
Re[3]: шаблоны С++ и дженерики С#
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.09.09 14:41
Оценка:
Здравствуйте, kochetkov.vladimir, Вы писали:

KV>А я хз, какая По мне, так необходимость в этом трюке говорит о проблемах с дизайном Но рассуждать об этом в контексте сравнения плюсов и шарпа было как-то неинтересно


Ну, а тогда какой смысл влезать в подобный спор?

У Карслона, по-моему, было замечательное высказывание:

Не на все вопросы, малыш, можно однозначно ответить "да" или "нет". Вот например — "Ты уже бросил пить коньяк по утрам?".


Точно так же и тут. На такие притязания нельзя дать прямой правильный ответ.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: от модератора
От: Кодт Россия  
Дата: 10.09.09 16:32
Оценка: 10 (1) +5
VD>Правильный ответ на притязания С++-ников — в языках с дженериками надо использовать другие паттерны, другие подходы, другие идеомы. Однако С++-ники никогда не поймут этого, так как они мыслят паттернами характерными для С++, которые заучены ими за долгую (или не очень) практику программирования на этом языке.
Напоминаю закон нетикета: отучаемся говорить за всех.
Любой дальнейший флейм на эту тему, по шаблону "дурак-самдурак-вседураки" будет пресекаться, возможно, жестоко.
Перекуём баги на фичи!
Re[2]: шаблоны С++ и дженерики С#
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.09.09 17:35
Оценка: -2
Здравствуйте, VladD2, Вы писали:

VD>Однако С++-ники никогда не поймут этого, так как они мыслят паттернами характерными для С++, которые заучены ими за долгую (или не очень) практику программирования на этом языке.


Поясню тем, кто не понял это самостоятельно, что я понимаю под термином С++-ник.

С++-ник — это не человек хорошо владеющий С++ или просто умеющий писать на нем.
С++-ник это человек знающий (не важно как) С++, и только его!
С++-ник человек думающий исключительно терминами С++ и воспринимающий все программирование через его призму.

Точно так же человек может быть сищарпщиком, немерлистом, лиспером или эрлэнгистом.
Главное тут — это однобокость взглядов.

При этом есть множество людей знающих (опять же не важно как хорошо) С++, но при этом отдающим себя отчет, что есть и другие идиомы.

Пока в споре люди будут причислять себя к некоторому лагерю, они никогда не поймут оппонентов, так как они просто будут мыслить отличными категориями.

Посему когда я говорю "Однако С++-ники никогда не поймут этого, так как они мыслят паттернами характерными для С++" я не говорю за всех кто знает С++, а просто констатирую факт особенности человеческого мышления.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: шаблоны С++ и дженерики С#
От: Кодт Россия  
Дата: 10.09.09 20:01
Оценка: 11 (1) +3 :)
Здравствуйте, VladD2, Вы писали:

VD>Поясню тем, кто не понял это самостоятельно, что я понимаю под термином С++-ник.

<...>

Ну а стоит ли устраивать бой с тенью? Сперва неявно ввёл воображаемого оппонента, а потом начал наголову его громить.
Да ещё и весьма произвольно использовал термин.

"Тракторист — это не тот, кто умеет водить трактор; и не тот, кто зарабатывает вождением трактора; это человек, которому всюду мерещатся трактора — от феррари до аэробуса".

Немудрено, что профессиональные С++ники "не поняли".

Ладно; определённость — пусть даже несколько неожиданная — появилась, можем в эту сторону не развивать разговор.
Перекуём баги на фичи!
Re[4]: шаблоны С++ и дженерики С#
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.09.09 20:41
Оценка: -1
Здравствуйте, Кодт, Вы писали:

К>Ну а стоит ли устраивать бой с тенью? Сперва неявно ввёл воображаемого оппонента, а потом начал наголову его громить.

К>Да ещё и весьма произвольно использовал термин.

На мой взгляд термин в самый рез. Он же не один в поле использован? Он в контексте использован.

К>"Тракторист — это не тот, кто умеет водить трактор; и не тот, кто зарабатывает вождением трактора; это человек, которому всюду мерещатся трактора — от феррари до аэробуса".


Если убрать слово "мерещится", то так оно и есть. Тракторист который кроме всего прочего ездит еще и на легковушке уже не будет думать о всех средствах передвижения как о тракторе.

К>Ладно; определённость — пусть даже несколько неожиданная — появилась, можем в эту сторону не развивать разговор.


+1
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: шаблоны С++ и дженерики С#
От: Геннадий Васильев Россия http://www.livejournal.com/users/gesha_x
Дата: 22.09.09 05:50
Оценка: +1
Здравствуйте, VladD2, Вы писали:

VD>Да, полноценного множественного наследования (МН) на дженериках не реализовать. Но так же точно на шаблонах нельзя реализовать даже что-то похожее на компонентность.


Что ты несёшь... заблуждения в массы? Компонентность реализуется инфраструктурой, а не классами, шаблонами или дженериками. Инфраструктурой и сопутствующими соглашениями. Нету инфраструктуры — нету компонентности. Есть инфраструктура — будет тебе компонентность хоть на бейсике.
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Re[2]: шаблоны С++ и дженерики С#
От: Хвост  
Дата: 22.09.09 09:50
Оценка: +1 -2
Здравствуйте, VladD2, Вы писали:

VD>Правильный ответ на притязания С++-ников — в языках с дженериками надо использовать другие паттерны, другие подходы, другие идеомы. Однако С++-ники никогда не поймут этого, так как они мыслят паттернами характерными для С++, которые заучены ими за долгую (или не очень) практику программирования на этом языке.


простите барин, это бред.

P.S.
и не надо строить из себя интеллект. Лично по твоим постам (и по твоим мегаисходникам столетней давности в которых ты осилил RAII в С++ и смог обернуть хендлы win32) у меня абсолютно стойкое убеждение что ты С++ знаешь максимум на уровне "Си с классами". Т.к. других сведений о твоей компетенции в С++ у меня нет, то и слушать твои росказни о С++(никах) нет желания.

P.P.S.
и напоследок, у тебя клёвая идеология. То что есть в С++ и С++ники указывают на отсутствие этого в других языках это по-твоему "закостенелость сознания, неумение видить другие идиомы, подходы". Зато с обратной стороны ты готов ... изойтись указывая на то что отсутствует в С++. Может ты просто не умеешь использовать "другие паттерны, другие подходы" ?
People write code, programming languages don't.
Re[4]: шаблоны С++ и дженерики С#
От: ZevS Россия  
Дата: 22.09.09 15:01
Оценка: :)
Здравствуйте, VladD2, Вы писали:

VD>

VD>Не на все вопросы, малыш, можно однозначно ответить "да" или "нет". Вот например — "Ты уже бросил пить коньяк по утрам?".


Да.

VD>На такие притязания нельзя дать прямой правильный ответ.


Нет.

Шутка.
Re[3]: шаблоны С++ и дженерики С#
От: VladD2 Российская Империя www.nemerle.org
Дата: 22.09.09 16:22
Оценка:
Здравствуйте, Геннадий Васильев, Вы писали:

ГВ>Что ты несёшь... заблуждения в массы?


Тебе это только кажется.

ГВ>Компонентность реализуется инфраструктурой, а не классами, шаблонами или дженериками. Инфраструктурой и сопутствующими соглашениями. Нету инфраструктуры — нету компонентности. Есть инфраструктура — будет тебе компонентность хоть на бейсике.


Как раз бэйсике она была заложена в язык начиная с 3-ей версии.
А вот в С++ компонентности не было, нет и, похоже, уже не будет.

Дженерике же проектировались с расчетом на компонентные решения.

В общем, сам ты несешь... заблуждения в массы. Наличие COM-а а так же разных ATL-ов и расширений MFC четко демонстрирует, что сам язык не компонентный и ему требуется "инфрастркутура" (читай, костыли) чтобы добиться оной.
Когда же язык и его рантайм исходно поддерживают компонентность, то костыли не требуются. Любой класс является компонентом и может быть использован в рантайме без дополнительных приседаний.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: шаблоны С++ и дженерики С#
От: Геннадий Васильев Россия http://www.livejournal.com/users/gesha_x
Дата: 23.09.09 06:12
Оценка: -1 :)
Здравствуйте, VladD2, Вы писали:

ГВ>>Компонентность реализуется инфраструктурой, а не классами, шаблонами или дженериками. Инфраструктурой и сопутствующими соглашениями. Нету инфраструктуры — нету компонентности. Есть инфраструктура — будет тебе компонентность хоть на бейсике.

VD>Как раз бэйсике она была заложена в язык начиная с 3-ей версии.

Угу, на основе инфраструктуры COM.

VD>А вот в С++ компонентности не было, нет и, похоже, уже не будет.


И это есть хорошо и хорошо весьма. Поскольку выбор компонентных инфраструктур весьма велик. В общем, в этом и прелесть C++ по сравнению с навороченными вагонами всех-правильных-практик в одном флаконе. (Язвительне комментарии по поводу того, что в C++ совсем нет правильных практик ==> /dev/null/please)

VD>Дженерике же проектировались с расчетом на компонентные решения.


Читай: в расчёте на инфраструктуру .Net.

VD>В общем, сам ты несешь... заблуждения в массы. Наличие COM-а а так же разных ATL-ов и расширений MFC четко демонстрирует, что сам язык не компонентный и ему требуется "инфрастркутура" (читай, костыли) чтобы добиться оной.


COM — это одна из возможных инфрастуктур. Понимаешь? Одна из мириад возможных. Чтобы ввести в язык "компонентность" сначала необходим некоторый набор соглашений, соответствующий этой самой инфраструктуре. Что за чем создаётся, что чем управляет, кто кому и как сигналит и т.п. Любая ОС — это компонентная инфраструктура, кстати (соглашения о формате файлов, о файловых системах и т.п.). Отсюда мораль: COM-приблуды MFC, ATL и вся остальная требуха свидетельствует только о том, что C++ может поддерживать, в числе прочих и такую компонентную инфраструктуру (привет капитану Очевидность).

VD>Когда же язык и его рантайм исходно поддерживают компонентность, то костыли не требуются. Любой класс является компонентом и может быть использован в рантайме без дополнительных приседаний.


Угу, угу. Осталось только уточнить, какая именно компонентность полагается самой правильной — вплоть до ABI.
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.