Еще один вопрос из серии : поиск не работает, если что не ругайтесь
Вот есть виртуальные функции, есть возможность создавать перегруженные виртуальные функции.
В чем проблемма(для компилятора и для стандарта) разрешить использование шаблонов виртуальных функций ?
PS Кажется кто-то не очень давно постил пример "обхода" этого запрета. Может быть повторите ?
Здравствуйте, dip_2000, Вы писали:
_>Вот есть виртуальные функции, есть возможность создавать перегруженные виртуальные функции. _>В чем проблемма(для компилятора и для стандарта) разрешить использование шаблонов виртуальных функций ? _>PS Кажется кто-то не очень давно постил пример "обхода" этого запрета. Может быть повторите ? _>
Проблема в том, что не ясно что хочешь
Общая идея такая, что когда функция вертуальная, то клиентсикй код может не знать о том, какие реализации были на самом деле реализованы. А сам код перегруженной функции может не знать о том, какие контексты используют его вызов. Типа всё хорошо. Можно вообще в любом порядке реализовывать.
А вот если придумать "шаблонную виртуальную" функцию, то получится, что клиент должен как-то сообщить в реализацию контекст вызова. В этмо месте возникает противоречие. Если ты согласен чем-то поступииться, то можно как-то реализовать...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Ровно пготому же.
Вот представь себе что ты реализуешь себе наследника SomeClassWithOperator, в котором определяешь putToStream для каких-то там типов, потом компилируешь это всё, засовываешь в плагин и поставялешь куда-то пользователю.
Потом ты приделываешь ещё другой плагин, в котором появляется новый тип потока. При этом права на наследника принадлежат тебе и ты никому не кажешь сорцы, а права на новый поток принадлежат третей фирме и она никому не кажется сорцы. Кто скомпилирует код твоего наследника для этого потока? И где он возьмёт узнает этот код?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
E>>Проблема в том, что не ясно что хочешь
_>А я немного поконкретнее вопрос поставлю:
Вот и давай посмотим с конкретной стороны. Таблица виртуальных функций — популярный способ реализации механизма позднего связывания. При такой реализации каждой виртуальной функции соответствует запись в таблице.
Теперь о шаблонах: для каждого типа при инстанциировании шаблона создается своя уникальная функция.
Внимание вопрос: каким образом должна заполняться таблица виртуальных функций в этом случае?
Здравствуйте, Bell, Вы писали:
B>Теперь о шаблонах: для каждого типа при инстанциировании шаблона создается своя уникальная функция. B>Внимание вопрос: каким образом должна заполняться таблица виртуальных функций в этом случае?
1) Например в соответсвующей ячейке может стоят map из типа апарметров в реализацию...
2) таблица виртуальных функций -- не догма...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
E>И где он возьмёт узнает этот код?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Сдаюсь... вы правы.
Но нет ли возможности это как то обойти ? Для данного конкретного случая, когда все типы известны на стадии компиляци, и единственная цель — не плодить кода похожего друг на друга как 2 капли воды?
Здравствуйте, Erop, Вы писали:
E>1) Например в соответсвующей ячейке может стоят map из типа апарметров в реализацию...
Да, наверное. Устроят ли всех такие затраты при вызове виртуальной функции — не уверен... E>2) таблица виртуальных функций -- не догма...
Я этого и не говорил
Здравствуйте, dip_2000, Вы писали:
_> Сдаюсь... вы правы. _>Но нет ли возможности это как то обойти ? Для данного конкретного случая, когда все типы известны на стадии компиляци, и единственная цель — не плодить кода похожего друг на друга как 2 капли воды? _> _>PS Ну кроме макросов.
Здравствуйте, Bell, Вы писали:
E>>1) Например в соответсвующей ячейке может стоят map из типа апарметров в реализацию... B>Да, наверное. Устроят ли всех такие затраты при вызове виртуальной функции — не уверен...
Ну map может быть очень быстрым, таки. индекс контекста можно генерироватьодин раз, при инициализации программы
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, dip_2000, Вы писали:
_>А я немного поконкретнее вопрос поставлю: _>Почему я могу так
_>class SomeClassWithAllOperator<<
Не можешь. Что за странное имя у класса?
На самом деле, попробуй представить, как могло бы быть реализовано то, что ты пожелал.
Вот у тебя есть базовый класс с шаблоном виртуальной функции. И есть класс-наследник.
1) Как наследник перекроет шаблон — полностью или выборочно — так, что по указателю на базу мы сможем вызвать перекрытую функцию?
2) Пусть
— мы скомпилировали наследника в единице трансляции x.cpp
— в единице трансляции y.cpp завели код, скрещивающий базу с типом Y (про наследника здесь ничего не известно)
— в единице трансляции z.cpp создали экземпляр наследника (про тип Y здесь ничего не известно) и передали как указатель на базу в функцию из y.cpp
В принципе такая задача решаема. Но не средствами компилятора С++, а ручками.
Например, в Haskell или O'Haskell в шаблон функции неявно передаётся комплект примитивных функций над типом аргумента. Поэтому шаблон не является шаблоном в С++ном смысле, это скорее паттерн "шаблонный метод" (Template Method).
Здравствуйте, dip_2000, Вы писали:
_>PS Кажется кто-то не очень давно постил пример "обхода" этого запрета. Может быть повторите ?
Повторять не буду, так как это было очень сложно. Ты можешь попробовтаь решить свою проблему проще. Например так:
class AbstractStream {
public:
virtual AbstractStream& operator << ( int ) = 0;
virtual AbstractStream& operator << ( const char* ) = 0;
// и т. д.
};
template<class TRealStream>
class CStreamProxy : public AbstractStream {
public:
CStreamProxy( TRealStream& theStream_ ) : theStream( theStream_ ) {}
virtual AbstractStream& operator << ( int v ) { return doIt( v ); }
virtual AbstractStream& operator << ( const char* ) { return doIt( v ); }
// и т. д.private:
TRealStream& theStream;
template<typename T> AbstractStream& doIt( T v )
{
theStream << v;
return *this;
}
};
Ну а в наследниках смело перекрываешь doDumpIt да и пишешь как хочешь
Если такое определение CStreamProxy кажется тебе слишком громоздким, можешь немного "упростить" это дело при помощи boost::mpl или какой-нибудь конструкции из макросов.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Нигде не возмет. Но виртуальность тут не при чем и аргументация мимо кассы. В случае обычной невиртуальной шаблонной функции будут ровно те же проблемы. И собственно виртуальные шаблонные функции были бы применимы (если б были бы реализованы) в таких же условиях, где и просто шаблонные. Да и вообще, авторы стандарта вряд ли думали насчет поддержки плагинов.
Posted via RSDN NNTP Server 2.1 beta
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Здравствуйте, Sergey, Вы писали:
S>Нигде не возмет. Но виртуальность тут не при чем и аргументация мимо кассы. В случае обычной невиртуальной шаблонной функции будут ровно те же проблемы. И собственно виртуальные шаблонные функции были бы применимы (если б были бы реализованы) в таких же условиях, где и просто шаблонные. Да и вообще, авторы стандарта вряд ли думали насчет поддержки плагинов.
Я сначала объяснил более абстрактно что мешает. Потом более конкретно. О раздельной компиляции авторы стандарта наверное думали? Ну так вот шаблонные виртуальные методы противоречат принципу раздельнйо компиляции.
Так верно?
Просто так не понятно. На примере, ИМХО, понятнее.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, dip_2000, Вы писали:
_> Сдаюсь... вы правы. _>Но нет ли возможности это как то обойти ? Для данного конкретного случая, когда все типы известны на стадии компиляци, и единственная цель — не плодить кода похожего друг на друга как 2 капли воды? _> _>PS Ну кроме макросов.
> S>Нигде не возмет. Но виртуальность тут не при чем и аргументация мимо кассы. В случае обычной невиртуальной шаблонной функции будут ровно те же проблемы. И собственно виртуальные шаблонные функции были бы применимы (если б были бы реализованы) в таких же условиях, где и просто шаблонные. Да и вообще, авторы стандарта вряд ли думали насчет поддержки плагинов. > > Я сначала объяснил более абстрактно что мешает. Потом более конкретно. О раздельной компиляции авторы стандарта наверное думали? Ну так вот шаблонные виртуальные методы противоречат принципу раздельнйо компиляции.
Вот конкретика насчет плагинов — она вообще не в тему. Опять же, обычные шаблонные методы (равно как и просто inline) тоже противоречат принципу раздельной компиляции (если не принимать в расчет экзотику типа экспорта шаблонов).
Posted via RSDN NNTP Server 2.1 beta
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Здравствуйте, Sergey, Вы писали:
S>Вот конкретика насчет плагинов — она вообще не в тему. Опять же, обычные шаблонные методы (равно как и просто inline) тоже противоречат принципу раздельной компиляции (если не принимать в расчет экзотику типа экспорта шаблонов).
Правда? А чего нет в C++ раздельной компиляции или шаблонов?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
> S>Вот конкретика насчет плагинов — она вообще не в тему. Опять же, обычные шаблонные методы (равно как и просто inline) тоже противоречат принципу раздельной компиляции (если не принимать в расчет экзотику типа экспорта шаблонов). > > Правда? А чего нет в C++ раздельной компиляции или шаблонов?
Раздельной компиляции шаблонов, разумеется. На практике нет — в стандарте она предусмотрена. Пока предусмотрена
Posted via RSDN NNTP Server 2.1 beta
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.