Ограничение на тип аргумента шаблона
От: Андрей Е  
Дата: 21.07.11 03:20
Оценка:
Есть шаблон функции. Он предназначен для работы с потомками некоторого базового класса. Реализовать его как просто функцию, работающую с базовым классом нельзя, так как он должен принимать и возвращать именно производный тип.

И хочется, чтобы этот шаблон не компилировался при попытке использовать его с классом не унаследованным от нашего базового класса, даже если у него есть все такие же функции, как и в базовом классе.

Пример:
class IReferenceCounted
{
public:
  void grab();
  bool drop();
};

// boost::intrusive_ptr при создании увеличивает счетчик ссылок на 1
// А класс IReferenceCounted при создании делает свой счетчик ссылок равным 1
// поэтому для корректной работы с IReferenceCounted нужно уменьшить счетчик ссылок сразу после создания
template <typename T>
boost::intrusive_ptr<T> create_intrusive(T* t)
{
    boost::intrusive_ptr<T> ptr(t);
    t->drop();
    return ptr;
}

В данном случае, функция create_intrusive должна принимать только указатель на объект производный от IReferenceCounted и возвращать умный указатель на него же. Но она не должна работать с другими типами, даже если у них есть функции grab и drop, так как у них скорей всего при создании счетчик ссылок будет равен нулю и функция не будет работать корректно.


Существует ли какой-то стандартный/правильный/простой и понятный способ сделать это?
Re: Ограничение на тип аргумента шаблона
От: wander  
Дата: 21.07.11 05:02
Оценка: 1 (1)
Здравствуйте, Андрей Е, Вы писали:

АЕ>Пример:

АЕ>
АЕ>class IReferenceCounted
АЕ>{
АЕ>public:
АЕ>  void grab();
АЕ>  bool drop();
АЕ>};

АЕ>// boost::intrusive_ptr при создании увеличивает счетчик ссылок на 1
АЕ>// А класс IReferenceCounted при создании делает свой счетчик ссылок равным 1
АЕ>// поэтому для корректной работы с IReferenceCounted нужно уменьшить счетчик ссылок сразу после создания
АЕ>template <typename T>
АЕ>boost::intrusive_ptr<T> create_intrusive(T* t, typename boost::enable_if<boost::is_base_of<IReferenceCounted, T> >::type* = 0)
АЕ>{
АЕ>    boost::intrusive_ptr<T> ptr(t);
    t->>drop();
АЕ>    return ptr;
АЕ>}
АЕ>


АЕ>Существует ли какой-то стандартный/правильный/простой и понятный способ сделать это?


enable_if и type_traits из boost. Смотри выделенное.
Re: Ограничение на тип аргумента шаблона
От: wvoquine  
Дата: 21.07.11 05:14
Оценка: :)
Здравствуйте, Андрей Е, Вы писали:

Такой вариант чем не устраивает?
http://ideone.com/LBFSf
To be is to be the value of a variable
Re: Ограничение на тип аргумента шаблона
От: wvoquine  
Дата: 21.07.11 05:25
Оценка:
Здравствуйте, Андрей Е, Вы писали:

Эту тему, кстати, Саттер обсуждает, предлагая, помимо прочего, и такое:

template<typename D, typename B>
class IsDerivedFrom1
{
class No { };
class Yes { No no[3]; };

static Yes Test( B* ); // declared, but not defined
static No Test( ... ); // declared, but not defined

public:
enum { Is = sizeof(Test(static_cast<D*>(0))) == sizeof(Yes) };
};


http://www.gotw.ca/publications/mxc++-item-4.htm
To be is to be the value of a variable
Re[2]: Ограничение на тип аргумента шаблона
От: _nn_ www.nemerleweb.com
Дата: 21.07.11 06:00
Оценка:
Здравствуйте, wvoquine, Вы писали:

skip

Этот код подходит только к большинству случаев:
http://ideone.com/mJLdR
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re: Ограничение на тип аргумента шаблона
От: uzhas Ниоткуда  
Дата: 21.07.11 07:08
Оценка:
Здравствуйте, Андрей Е, Вы писали:

АЕ>Существует ли какой-то стандартный/правильный/простой и понятный способ сделать это?


самый понятный имхо — это вставить static_assert внутри функции (довольно декларативно описываем ограничения на типы):

template <typename T>
boost::intrusive_ptr<T> create_intrusive(T* t)
{
  static_assert(boost::is_base_of<IReferenceCounted, T>::value);
  boost::intrusive_ptr<T> ptr(t);
  t->drop();
  return ptr;
}


можно и так, но хуже

template <typename T>
boost::intrusive_ptr<T> create_intrusive(T* t)
{
  boost::intrusive_ptr<T> ptr(t);
  static_cast<IReferenceCounted*>(t)->drop();
  return ptr;
}

template <typename T>
boost::intrusive_ptr<T> create_intrusive(T* t, IReferenceCounted* internalT = t)
{
  boost::intrusive_ptr<T> ptr(t);
  internalT->drop();
  return ptr;
}
Re[2]: Ограничение на тип аргумента шаблона
От: Андрей Е  
Дата: 21.07.11 07:20
Оценка:
Здравствуйте, uzhas, Вы писали:

U>самый понятный имхо — это вставить static_assert внутри функции (довольно декларативно описываем ограничения на типы):


U>
U>template <typename T>
U>boost::intrusive_ptr<T> create_intrusive(T* t)
U>{
U>  static_assert(boost::is_base_of<IReferenceCounted, T>::value);
U>  boost::intrusive_ptr<T> ptr(t);
  t->>drop();
U>  return ptr;
U>}
U>


Во! То что нужно. Компактно, добавляется одна строчка. И понятно: из кода виден его смысл и предназначение.

На текущий момент у меня сделано так:

U>
U>template <typename T>
U>boost::intrusive_ptr<T> create_intrusive(T* t)
U>{
U>  boost::intrusive_ptr<T> ptr(t);
U>  static_cast<IReferenceCounted*>(t)->drop();
U>  return ptr;
U>}
U>


Этот вариант тоже компактный, то не совсем прозрачный. Пришлось добавить поясняющий комментарий.
Re[2]: Ограничение на тип аргумента шаблона
От: zaufi Земля  
Дата: 21.07.11 07:33
Оценка: +3
Здравствуйте, wander, Вы писали:

W>Здравствуйте, Андрей Е, Вы писали:


АЕ>>Пример:

АЕ>>
АЕ>>class IReferenceCounted
АЕ>>{
АЕ>>public:
АЕ>>  void grab();
АЕ>>  bool drop();
АЕ>>};

АЕ>>// boost::intrusive_ptr при создании увеличивает счетчик ссылок на 1
АЕ>>// А класс IReferenceCounted при создании делает свой счетчик ссылок равным 1
АЕ>>// поэтому для корректной работы с IReferenceCounted нужно уменьшить счетчик ссылок сразу после создания
АЕ>>template <typename T>
typename boost::enable_if<
    boost::is_base_of<IReferenceCounted, T>
  , boost::intrusive_ptr<T> 
  >::type
АЕ>>create_intrusive(T* t)
АЕ>>{
АЕ>>    boost::intrusive_ptr<T> ptr(t);
    t->>>drop();
АЕ>>    return ptr;
АЕ>>}
АЕ>>


АЕ>>Существует ли какой-то стандартный/правильный/простой и понятный способ сделать это?


W>enable_if и type_traits из boost. Смотри выделенное.

лучше так. зачем иметь лишний рантайм параметр...
Re[2]: Ограничение на тип аргумента шаблона
От: _nn_ www.nemerleweb.com
Дата: 21.07.11 08:49
Оценка: 13 (1)
Здравствуйте, uzhas, Вы писали:

U>Здравствуйте, Андрей Е, Вы писали:


АЕ>>Существует ли какой-то стандартный/правильный/простой и понятный способ сделать это?


U>самый понятный имхо — это вставить static_assert внутри функции (довольно декларативно описываем ограничения на типы):


Но не самый оптимальный.
Имея static_assert внутри функции, при ошибке компилятор будет указывать на строку внутри функции, а не на вызывающую строку как с enable_if.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[2]: Ограничение на тип аргумента шаблона
От: jazzer Россия Skype: enerjazzer
Дата: 21.07.11 23:28
Оценка: 18 (4)
Здравствуйте, uzhas, Вы писали:

U>Здравствуйте, Андрей Е, Вы писали:


АЕ>>Существует ли какой-то стандартный/правильный/простой и понятный способ сделать это?


U>самый понятный имхо — это вставить static_assert внутри функции (довольно декларативно описываем ограничения на типы):


У static_assert и enable_if принципиально разная семантика.

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

enable_if работает иначе — функция просто удаляется из списка кандидатов при поиске функции, тело функции не будет инстанцироваться, а ошибка будет всего одна типа "функция не найдена" и будет указывать в место вызова. Плюс могут подойти и будут выбраны другие функции с меньшими ограничениями — это невозможно с static_assert (см. здесь, например: http://www.rsdn.ru/forum/cpp/3722136.1.aspx
Автор: jazzer
Дата: 02.03.10
). Это из плюсов.
Минус всего один — удаление функции происходит молча и ты не знаешь, какое именно условие не сработало. В результате частенлько бывает так, что у тебя есть десяток функций, защищенных разными enable_if, и ни одна не подходит — придется сидеть и разбираться, как так совпало (это не так страшно, но нужен навык).
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]: Не понимаю...
От: Олег К.  
Дата: 21.07.11 23:56
Оценка:
U>>самый понятный имхо — это вставить static_assert внутри функции (довольно декларативно описываем ограничения на типы):

U>>
U>>template <typename T>
U>>boost::intrusive_ptr<T> create_intrusive(T* t)
U>>{
U>>  static_assert(boost::is_base_of<IReferenceCounted, T>::value);
U>>  boost::intrusive_ptr<T> ptr(t);
  t->>>drop();
U>>  return ptr;
U>>}
U>>


АЕ>Во! То что нужно. Компактно, добавляется одна строчка. И понятно: из кода виден его смысл и предназначение.


АЕ>На текущий момент у меня сделано так:


U>>
U>>template <typename T>
U>>boost::intrusive_ptr<T> create_intrusive(T* t)
U>>{
U>>  boost::intrusive_ptr<T> ptr(t);
U>>  static_cast<IReferenceCounted*>(t)->drop();
U>>  return ptr;
U>>}
U>>


АЕ>Этот вариант тоже компактный, то не совсем прозрачный. Пришлось добавить поясняющий комментарий.


Вот не понимаю. Какую-такую задачу ты решаешь что без темплейтов, static_assert-ов и прочих извратов ну совсем никак?
Re[4]: Не понимаю...
От: jazzer Россия Skype: enerjazzer
Дата: 22.07.11 00:50
Оценка:
Здравствуйте, Олег К., Вы писали:

ОК>Вот не понимаю. Какую-такую задачу ты решаешь что без темплейтов, static_assert-ов и прочих извратов ну совсем никак?


Это была попытка флейма? С каких это пор стандартные средства языка стали извратами?
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[5]: Не понимаю...
От: Олег К.  
Дата: 22.07.11 01:03
Оценка: 1 (1) +1 :))
ОК>>Вот не понимаю. Какую-такую задачу ты решаешь что без темплейтов, static_assert-ов и прочих извратов ну совсем никак?

J>Это была попытка флейма? С каких это пор стандартные средства языка стали извратами?


Нет. Это не попытка флейма. Я действительно не понимаю какие такие задачи решает большинство посетителей этого форума что им просто жизненно необходимо запихать в код как можно больше фич языка С++.

Исходя из собственного опыта, считаю что для того чтобы писать нормальный и понятный код нужно процентов тридцать языка. Ну а то что в плюсах есть куча фич — так это еще не значит что их непременно нужно использовать.
Re[6]: Не понимаю...
От: jazzer Россия Skype: enerjazzer
Дата: 22.07.11 02:29
Оценка: +2
Здравствуйте, Олег К., Вы писали:

ОК>>>Вот не понимаю. Какую-такую задачу ты решаешь что без темплейтов, static_assert-ов и прочих извратов ну совсем никак?


J>>Это была попытка флейма? С каких это пор стандартные средства языка стали извратами?


ОК>Нет. Это не попытка флейма. Я действительно не понимаю какие такие задачи решает большинство посетителей этого форума что им просто жизненно необходимо запихать в код как можно больше фич языка С++.


задача у всех одна — написать прозрачный и безопасный код и переложить как можно больше проверок (а то и кодогенерации) на компилятор.

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


Знаешь, есть хорошее соображение насчет того, что в любом продукте 80% пользователей используют только 20% фич. Беда только в том, что у каждого пользователя эти 20% свои.
Аналогично, для каждой задачи может быть достаточно 30% языка, но у каждой задачи эти 30% будут свои.

Причем утверждение "как можно больше фич" не совсем верно, правильнее сказать так: "как можно больше безопасных высокоуровневых фич, чтоб не пользоваться опасными низкоуровневыми". Т.е. остаются все те же 30%, просто они другие — не в области жонглирования битами, указателями на void и прочими прелестями сишного подмножества. Не говоря уже о фиче "а это требование мы просто в комментарии перед функцией напишем".

Всегда, когда тебе нужно выразить в коде зависимость от типов, она наиболее прямолинейно решается шаблонами.
Иногда можно добиться результатов перегрузкой, но вот это в большинстве случаев действительно будет извратом (например, для перегрузки нужен по крайней мере объект соответствующего типа).
Тем более что и static_assert, и enable_if выражают условие максимально декларативно и пишутся в одну строчку.
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[7]: Не понимаю...
От: Олег К.  
Дата: 22.07.11 04:30
Оценка:
ОК>>>>Вот не понимаю. Какую-такую задачу ты решаешь что без темплейтов, static_assert-ов и прочих извратов ну совсем никак?

J>>>Это была попытка флейма? С каких это пор стандартные средства языка стали извратами?


ОК>>Нет. Это не попытка флейма. Я действительно не понимаю какие такие задачи решает большинство посетителей этого форума что им просто жизненно необходимо запихать в код как можно больше фич языка С++.


J>задача у всех одна — написать прозрачный и безопасный код и переложить как можно больше проверок (а то и кодогенерации) на компилятор.


Это разве задача? Я о бизнес задаче, если что.

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

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


J>Знаешь, есть хорошее соображение насчет того, что в любом продукте 80% пользователей используют только 20% фич. Беда только в том, что у каждого пользователя эти 20% свои.

J>Аналогично, для каждой задачи может быть достаточно 30% языка, но у каждой задачи эти 30% будут свои.

J>Причем утверждение "как можно больше фич" не совсем верно, правильнее сказать так: "как можно больше безопасных высокоуровневых фич, чтоб не пользоваться опасными низкоуровневыми". Т.е. остаются все те же 30%, просто они другие — не в области жонглирования битами, указателями на void и прочими прелестями сишного подмножества. Не говоря уже о фиче "а это требование мы просто в комментарии перед функцией напишем".


Вообще-то можно и нужно писать высокоуровневый код в котором просто не нужны никакие дополнительные проверки. Он и так будет по себе безопасен. А тут люди ставят себя в такие рамки и делают все что угодно но только не то что нужно.

И этот высокоуровневый код и будет содержать где-то процентов тридцать языка. Ты сам согласился с этим выше.

J>Всегда, когда тебе нужно выразить в коде зависимость от типов, она наиболее прямолинейно решается шаблонами.


Ну я знаю что решается шаблонами и могу тоже писать в стиле Александреску. Вопрос в другом: нужно ли это? Мой ответ — ни разу ни нужно. Какая-то подмена понятий здесь.

J>Иногда можно добиться результатов перегрузкой, но вот это в большинстве случаев действительно будет извратом (например, для перегрузки нужен по крайней мере объект соответствующего типа).

J>Тем более что и static_assert, и enable_if выражают условие максимально декларативно и пишутся в одну строчку.

Зачем это вообще нужно? Ты не ставь себя в такие рамки чтобы нужны были эти ассерты и инэйблы и будет тебе счастье.
Re[3]: Ограничение на тип аргумента шаблона
От: Юрий Жмеренецкий ICQ 380412032
Дата: 22.07.11 06:34
Оценка:
Здравствуйте, Андрей Е, Вы писали:


АЕ>На текущий момент у меня сделано так:


U>>
U>>template <typename T>
U>>boost::intrusive_ptr<T> create_intrusive(T* t)
U>>{
U>>  boost::intrusive_ptr<T> ptr(t);
U>>  static_cast<IReferenceCounted*>(t)->drop();
U>>  return ptr;
U>>}
U>>


Дополню: У intrusive_ptr есть такой конструктор — 'intrusive_::intrusive_ptr(T * p, bool add_ref = true)'
Re[8]: Не понимаю...
От: jazzer Россия Skype: enerjazzer
Дата: 22.07.11 07:21
Оценка:
Здравствуйте, Олег К., Вы писали:

ОК>>>>>Вот не понимаю. Какую-такую задачу ты решаешь что без темплейтов, static_assert-ов и прочих извратов ну совсем никак?


J>>>>Это была попытка флейма? С каких это пор стандартные средства языка стали извратами?


ОК>>>Нет. Это не попытка флейма. Я действительно не понимаю какие такие задачи решает большинство посетителей этого форума что им просто жизненно необходимо запихать в код как можно больше фич языка С++.


J>>задача у всех одна — написать прозрачный и безопасный код и переложить как можно больше проверок (а то и кодогенерации) на компилятор.


ОК>Это разве задача? Я о бизнес задаче, если что.


А бизнес-задача вообще никак не связана с язком программирования, не говоря уже о каких-то его фичах. Если что.

J>>Причем утверждение "как можно больше фич" не совсем верно, правильнее сказать так: "как можно больше безопасных высокоуровневых фич, чтоб не пользоваться опасными низкоуровневыми". Т.е. остаются все те же 30%, просто они другие — не в области жонглирования битами, указателями на void и прочими прелестями сишного подмножества. Не говоря уже о фиче "а это требование мы просто в комментарии перед функцией напишем".


ОК>Вообще-то можно и нужно писать высокоуровневый код в котором просто не нужны никакие дополнительные проверки. Он и так будет по себе безопасен. А тут люди ставят себя в такие рамки и делают все что угодно но только не то что нужно.

ОК>И этот высокоуровневый код и будет содержать где-то процентов тридцать языка. Ты сам согласился с этим выше.

Выше я говорил о высокоуровневых фичах языка, а не о коде, перечитай.
Высокоуровневый код строится на низкоуровневом коде, в котором все необходимые проверки будут. Вот этот низкоуровневый код надо как-то писать, правда?

J>>Всегда, когда тебе нужно выразить в коде зависимость от типов, она наиболее прямолинейно решается шаблонами.


ОК>Ну я знаю что решается шаблонами и могу тоже писать в стиле Александреску. Вопрос в другом: нужно ли это? Мой ответ — ни разу ни нужно. Какая-то подмена понятий здесь.


Замечательно, расскажи нам, как ты иначе выразишь в коде зависимость от типа. sizeof? dynamic_cast?

ОК>Зачем это вообще нужно? Ты не ставь себя в такие рамки чтобы нужны были эти ассерты и инэйблы и будет тебе счастье.


А мне и так счастье, но спасибо за заботу, конечно.
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[9]: Не понимаю...
От: Олег К.  
Дата: 24.07.11 22:06
Оценка:
ОК>>>>>>Вот не понимаю. Какую-такую задачу ты решаешь что без темплейтов, static_assert-ов и прочих извратов ну совсем никак?

J>>>>>Это была попытка флейма? С каких это пор стандартные средства языка стали извратами?


ОК>>>>Нет. Это не попытка флейма. Я действительно не понимаю какие такие задачи решает большинство посетителей этого форума что им просто жизненно необходимо запихать в код как можно больше фич языка С++.


J>>>задача у всех одна — написать прозрачный и безопасный код и переложить как можно больше проверок (а то и кодогенерации) на компилятор.


ОК>>Это разве задача? Я о бизнес задаче, если что.


J>А бизнес-задача вообще никак не связана с язком программирования, не говоря уже о каких-то его фичах. Если что.


Ну вообще-то решаются бизнес задачи с использованием конкретного языка программирования. Вопрос в том, сколько нужно задействовать фич данного языка для решения данной задачи? В данном случае я не увидел ничего относящегося к бизнес задаче.

J>>>Причем утверждение "как можно больше фич" не совсем верно, правильнее сказать так: "как можно больше безопасных высокоуровневых фич, чтоб не пользоваться опасными низкоуровневыми". Т.е. остаются все те же 30%, просто они другие — не в области жонглирования битами, указателями на void и прочими прелестями сишного подмножества. Не говоря уже о фиче "а это требование мы просто в комментарии перед функцией напишем".


ОК>>Вообще-то можно и нужно писать высокоуровневый код в котором просто не нужны никакие дополнительные проверки. Он и так будет по себе безопасен. А тут люди ставят себя в такие рамки и делают все что угодно но только не то что нужно.

ОК>>И этот высокоуровневый код и будет содержать где-то процентов тридцать языка. Ты сам согласился с этим выше.

J>Выше я говорил о высокоуровневых фичах языка, а не о коде, перечитай.

J>Высокоуровневый код строится на низкоуровневом коде, в котором все необходимые проверки будут. Вот этот низкоуровневый код надо как-то писать, правда?

Низкоуровневый код это if-ы, switch-и и циклы. Весь остальной изврат с темплейтами — это от лукавого.

J>>>Всегда, когда тебе нужно выразить в коде зависимость от типов, она наиболее прямолинейно решается шаблонами.


ОК>>Ну я знаю что решается шаблонами и могу тоже писать в стиле Александреску. Вопрос в другом: нужно ли это? Мой ответ — ни разу ни нужно. Какая-то подмена понятий здесь.


J>Замечательно, расскажи нам, как ты иначе выразишь в коде зависимость от типа. sizeof? dynamic_cast?


Я вообще не вижу нужды выражать зависимость от типа, но коли вы ставите себя в такие рамки...

На счет dynamic_cast-a — я не помню когда я его использовал в последний раз, если вообще использовал, но если я буду видеть что без него никак (в чем я очень сомневаюсь), то я таки использую dynamic_cast.

ОК>>Зачем это вообще нужно? Ты не ставь себя в такие рамки чтобы нужны были эти ассерты и инэйблы и будет тебе счастье.


J>А мне и так счастье, но спасибо за заботу, конечно.


В общем, принцип KISS не является чертой С++ программистов, и этот форум тому подтверждение.
Re[10]: Не понимаю...
От: jazzer Россия Skype: enerjazzer
Дата: 25.07.11 03:23
Оценка: +1 -1
Здравствуйте, Олег К., Вы писали:

Заканчивай с бессмысленным флеймом уже. Твоя религиозная позиция понятна.
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[10]: Не понимаю...
От: _nn_ www.nemerleweb.com
Дата: 25.07.11 08:10
Оценка:
Здравствуйте, Олег К., Вы писали:

ОК>Низкоуровневый код это if-ы, switch-и и циклы. Весь остальной изврат с темплейтами — это от лукавого.


Ну не скажите.
Вот вам пример digits_number
Автор: _nn_
Дата: 08.08.04
.

Как это сделать без шаблонов с if и switch ?

J>>>>Всегда, когда тебе нужно выразить в коде зависимость от типов, она наиболее прямолинейно решается шаблонами.


ОК>>>Ну я знаю что решается шаблонами и могу тоже писать в стиле Александреску. Вопрос в другом: нужно ли это? Мой ответ — ни разу ни нужно. Какая-то подмена понятий здесь.


А мне постоянно нужно.

Вот например, надоело каждый раз думать как вызывать find. Как метод или std::find.
Ведь для ассоциативных контейнеров вызов .find будет эфективней намного.

Делаешь простую функцию
template<typename Container, typename Value>
typename Container::iterator generic_find(Container& c, Value const& value);


А потом еще enable_if и еще для определения типа контейнера.

Зато потом в коде просто используешь generic_find и всегда будет вызов наиболее производительного кода.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.