Re: Ограничение на тип аргумента шаблона
От: Erop Россия  
Дата: 25.07.11 08:14
Оценка: -1
Здравствуйте, Андрей Е, Вы писали:

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


А зачем это надо? Типа с каким-то из корней надо работать по особенному? Тогда может быть лучше сделать XXX_traits, и полагаться на них?

С другой стороны, если с какой-то базой нужна прямо вот уж совсем особая работа, то может быть будет достаточно, чтобы функция не находилась? Ну, то есть, например, можно сделать так:
#include <iostream>
 
namespace Test {
   struct root {
      int count;
      root() : count( 1 ) {}
      static const char* name() { return "root"; }
   };
 
   template<typename T>
   void testIt( T& t ) { std::cout << t.name() << "::count == " << t.count << std::endl; }
 
}//namespace Test
 
using Test::root;
 
struct C1 : root {static const char* name() { return "C1"; }};
struct C2 { 
    int count; 
    C2() : count( -1 ) {} 
    static const char* name() { return "C2"; } 
};
 
template<typename T>
void test()
{
    T t;
    testIt( t );
}
 
int main()
{
    test<root>();    
    test<C1>();    
//    test<C2>();    
  return 0;
}
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[10]: Не понимаю...
От: wander  
Дата: 25.07.11 11:38
Оценка: +1 -1
Здравствуйте, Олег К., Вы писали:

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

Это может быть некая библиотека или общий для проекта функционал, который топикстартер стремится отипобезопасить с помощью "извратов с темплейтами". В этом нет никакого криминала.

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

Ты пишешь на С++? А то ты так говоришь, как будто нет. В С++ почти любой код выражает какую-то зависимость от типа.

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

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

ОК>В общем, принцип KISS не является чертой С++ программистов, и этот форум тому подтверждение.

Ничего сложного в этом нет.
Re[11]: Не понимаю...
От: Erop Россия  
Дата: 25.07.11 12:15
Оценка: +1
Здравствуйте, wander, Вы писали:

W>Это может быть некая библиотека или общий для проекта функционал, который топикстартер стремится отипобезопасить с помощью "извратов с темплейтами". В этом нет никакого криминала.


Я, конечно, всё понимаю, но как же люди раньше-то жили?
Кроме того, как-то мало понятно, чем утиная типизация-то не угодила?

W>При разработке сложных библиотек такое частенько бывает нужно. Иначе только в комментах писать про особенности, бывает даже рантайм проверку сделать проблематично. Так что, решение с темплейтами иногда даже очень соответствует KISS.


Мой опыт подсказывает мне, что обычно, чем лучше интерфейс библиотеки продуман и проработан, тем меньше нужно всяких хитрых ограничений, проверок и т. д. Хотя подходы к программированию бывают таки разные. Бывают и такие, что надо делать проверки. Просто каждый случай надо обсуждать КОНКРЕТНО.
В частности лично мне тоже нужда ТС подозрительна. Но если я его верно понял, то я знаю решение его задачки без boost'а

W>Ничего сложного в этом нет.

Если boost доступен, то да, нет.
Второе ограничение, это то, что мы подавляем генерацию слишком поздно, либо слишком криво.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[12]: Не понимаю...
От: jazzer Россия Skype: enerjazzer
Дата: 25.07.11 13:00
Оценка:
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, wander, Вы писали:


W>>Это может быть некая библиотека или общий для проекта функционал, который топикстартер стремится отипобезопасить с помощью "извратов с темплейтами". В этом нет никакого криминала.


E>Я, конечно, всё понимаю, но как же люди раньше-то жили?

Плохо жили. Забыл, как void* кастятся макросами ко всему на свете? Еще фортран можно вспомнить, тоже "удобный" язык.
А что, по версии Олега К, switch, if и циклы есть, а остальное — от лукавого.
Они и в асме есть, кстати. Чего еще придумывать, классы какие-то, функции...

E>Кроме того, как-то мало понятно, чем утиная типизация-то не угодила?

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

W>>При разработке сложных библиотек такое частенько бывает нужно. Иначе только в комментах писать про особенности, бывает даже рантайм проверку сделать проблематично. Так что, решение с темплейтами иногда даже очень соответствует KISS.


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

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

E>Хотя подходы к программированию бывают таки разные. Бывают и такие, что надо делать проверки. Просто каждый случай надо обсуждать КОНКРЕТНО.

+1. Поэтому я и называю весь этот разговор бессмысленным флеймом. Особенно попытки притянуть эту мелкую техническую деталь реализации к бизнес-задаче.

E>В частности лично мне тоже нужда ТС подозрительна. Но если я его верно понял, то я знаю решение его задачки без boost'а

Оно будет так же коротко и самодокументируемо, как static_assert или enable_if в паре с is_base_of?

W>>Ничего сложного в этом нет.

E>Если boost доступен, то да, нет.
Да даже если и недоступен, enable_if — это три строчки, а static_assert вообще в новом стандарте уже.

E>Второе ограничение, это то, что мы подавляем генерацию слишком поздно, либо слишком криво.

вот с этого места поподробнее, плиз. Или ты имеешь в виду то, что я писал здесь
Автор: jazzer
Дата: 22.07.11
?
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[13]: Не понимаю...
От: Erop Россия  
Дата: 25.07.11 14:05
Оценка:
Здравствуйте, jazzer, Вы писали:


E>>Я, конечно, всё понимаю, но как же люди раньше-то жили?

J>Плохо жили. Забыл, как void* кастятся макросами ко всему на свете? Еще фортран можно вспомнить, тоже "удобный" язык.
J>А что, по версии Олега К, switch, if и циклы есть, а остальное — от лукавого.
J>Они и в асме есть, кстати. Чего еще придумывать, классы какие-то, функции...

Ты утрируешь, возможно, что он тоже утрирует.
Фортран -- один из самых высокоуровневых языков, который я знаю. Ясен пень, что для своих задач, как и любой высокоуровневый язык.

Про касты макросами к void* я не очень понял о чём речь.

E>>Кроме того, как-то мало понятно, чем утиная типизация-то не угодила?

J>Километровыми сообщениями об ошибках, например.
J>Тем, что условия не выражены явно, вернее, вообще не выражены никак. У утиной типизации одно условие: "скомпилировалось или нет". Не скомпилировалось — вперед, ползай по исходникам, разбирайся, где твой тип не так крякнул.

Ну это вообще косяк шаблонов в С++ такой. Да, они уроды. Тут ничего не попишешь.
Но мы же не вообще уродство С++-шаблонов обсуждаем а задачу ТС? У ТС стоит требование наследоваться от определённого класса. А если не от него, а от его копии, то не компилируемся. Не очень понятно, зачем именно такое нужно.

J>Если библиотека шаблонная, то от ограничений и проверок не уйти никуда, если не хочется, конечно, брать пример с ортодоксальных версий STL c ее километровыми сообщениями об ошибках. А с нешаблонной библиотекой да, никаких проверок типов не нужно.


И не только типов. Выделенные значения -- тоже нехорошо. А если шаблонная, то да, это врождённое уродство у С++-шаблонов такое. Ничего не попишешь, приходиться юзать те костыли, которые доступны...

J>+1. Поэтому я и называю весь этот разговор бессмысленным флеймом. Особенно попытки притянуть эту мелкую техническую деталь реализации к бизнес-задаче.


Ну мне вот интересно, зачем такое требование таки понадобилось. IMHO, адекватное решение будет зависеть от того, зачем это таки надо...

J>Оно будет так же коротко и самодокументируемо, как static_assert или enable_if в паре с is_base_of?

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

E>>Второе ограничение, это то, что мы подавляем генерацию слишком поздно, либо слишком криво.

J>вот с этого места поподробнее, плиз. Или ты имеешь в виду то, что я писал здесь
Автор: jazzer
Дата: 22.07.11
?


Да, примерно это.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[2]: Ограничение на тип аргумента шаблона
От: jazzer Россия Skype: enerjazzer
Дата: 25.07.11 14:25
Оценка: :)
Здравствуйте, Erop, Вы писали:


 
template<class T>
struct C3 { 
    int count; 
    C3() : count( -1 ) {} 
    static const char* name() { return "C3"; } 
};

E>int main()
E>{
E>    test<root>();    
E>    test<C1>();    
E>//    test<C2>();    
    test< C3<root> >(); // OOPS!!!
E>  return 0;
E>}
E>

http://ideone.com/SGPJv

Егор, напиши 150 раз: "Я не будут больше хакерить без нужды, когда есть очевидные решения!"
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[14]: Не понимаю...
От: jazzer Россия Skype: enerjazzer
Дата: 25.07.11 14:29
Оценка:
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, jazzer, Вы писали:



E>>>Я, конечно, всё понимаю, но как же люди раньше-то жили?

J>>Плохо жили. Забыл, как void* кастятся макросами ко всему на свете? Еще фортран можно вспомнить, тоже "удобный" язык.
J>>А что, по версии Олега К, switch, if и циклы есть, а остальное — от лукавого.
J>>Они и в асме есть, кстати. Чего еще придумывать, классы какие-то, функции...

E>Ты утрируешь, возможно, что он тоже утрирует.

E>Фортран -- один из самых высокоуровневых языков, который я знаю. Ясен пень, что для своих задач, как и любой высокоуровневый язык.
О да. 100500 параллельных массивов — это очень высокоуровнево.

E>Про касты макросами к void* я не очень понял о чём речь.

Ну это реализация шаблонов средствами Си (и Java до generics, кстати). Это все к вопросу о том, как люди жили до шаблонов.

E>>>Кроме того, как-то мало понятно, чем утиная типизация-то не угодила?

J>>Километровыми сообщениями об ошибках, например.
J>>Тем, что условия не выражены явно, вернее, вообще не выражены никак. У утиной типизации одно условие: "скомпилировалось или нет". Не скомпилировалось — вперед, ползай по исходникам, разбирайся, где твой тип не так крякнул.

E>Ну это вообще косяк шаблонов в С++ такой. Да, они уроды. Тут ничего не попишешь.

Где именно косяк?
E>Но мы же не вообще уродство С++-шаблонов обсуждаем а задачу ТС? У ТС стоит требование наследоваться от определённого класса. А если не от него, а от его копии, то не компилируемся. Не очень понятно, зачем именно такое нужно.
Ты определись, либо мы обсуждаем задачу ТС, либо предложенную тобой утиную типизацию.

J>>Если библиотека шаблонная, то от ограничений и проверок не уйти никуда, если не хочется, конечно, брать пример с ортодоксальных версий STL c ее километровыми сообщениями об ошибках. А с нешаблонной библиотекой да, никаких проверок типов не нужно.


E>И не только типов. Выделенные значения -- тоже нехорошо. А если шаблонная, то да, это врождённое уродство у С++-шаблонов такое. Ничего не попишешь, приходиться юзать те костыли, которые доступны...

Ты про уродство шаблонов говоришь в контексте непринятых в будущий стандарт концептов? Или что?

J>>+1. Поэтому я и называю весь этот разговор бессмысленным флеймом. Особенно попытки притянуть эту мелкую техническую деталь реализации к бизнес-задаче.

E>Ну мне вот интересно, зачем такое требование таки понадобилось. IMHO, адекватное решение будет зависеть от того, зачем это таки надо...
Ну уж точно это не будет иметь отношения к бизнес-задаче, до нее еще 15 этажей топать наверх.

J>>Оно будет так же коротко и самодокументируемо, как static_assert или enable_if в паре с is_base_of?

E>Даже лучше. Надо просто базу и связанные с ней шаблоны функций поместить в отдельное пространство имён. Потом базу, при помощи used вытащить в нужное, и вуаля. Для ненаследников эти шаблоны просто не найдутся, без всяких хаккерств и трюков...
E>Я его уже приводил в этой теме...
Вуаля, говоришь? Да, видел. Несерьезно, я думаю, ты сам это понимаешь. Это именно хакерство и трюки, причем кривые: http://ideone.com/SGPJv
Не говоря уже о, гыгы, самодокументированности.
Вот каким боком человек, читающий код, должен догадаться, что помещение класса в данное пространство имен — это не архитектурное решение в рамках декомпозиции программы, а только чтоб шаблонная функция тремя экранами ниже смогла всосать только этот класс и его производные?
Признайся, что ты троллишь, я не верю, чтоб ты это "решение" всерьез предлагал.

E>>>Второе ограничение, это то, что мы подавляем генерацию слишком поздно, либо слишком криво.

J>>вот с этого места поподробнее, плиз. Или ты имеешь в виду то, что я писал здесь
Автор: jazzer
Дата: 22.07.11
?


E>Да, примерно это.

ОК. Про "слишком поздно" я написал. Про "слишком криво" — нет. Так что рассказывай.
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[15]: Не понимаю...
От: Erop Россия  
Дата: 25.07.11 15:44
Оценка:
Здравствуйте, jazzer, Вы писали:

E>>Ты утрируешь, возможно, что он тоже утрирует.

E>>Фортран -- один из самых высокоуровневых языков, который я знаю. Ясен пень, что для своих задач, как и любой высокоуровневый язык.
J>О да. 100500 параллельных массивов — это очень высокоуровнево.

Для вычматов фортран нереально удобен.
J>Ну это реализация шаблонов средствами Си (и Java до generics, кстати). Это все к вопросу о том, как люди жили до шаблонов.
Давай обсудим аду, там всякую с модулой?

E>>Ну это вообще косяк шаблонов в С++ такой. Да, они уроды. Тут ничего не попишешь.

J>Где именно косяк?
1) И в каком месте в шаблонах С++ можно формально описать требования на параметры?
2) И кто и как гарантирует, что требования исчерпывающие, кстати?

J>Ты определись, либо мы обсуждаем задачу ТС, либо предложенную тобой утиную типизацию.

Мы обсуждаем задачу ТС. Читай правила форума.

В частности ТС сказал, что ему надо запретить параметру шаблона не быть наследником определённого класса. То есть, фактически, запретить утиниую типизацию. Так?
Кстати, про то, что наследники бывают приватные там всякие, множественные и прочее ТС ничего не сказал вроде как. Я думаю он забыл про это упомянуть, но фиг его знает, что ему на самом деле-то надо...

J>Ты про уродство шаблонов говоришь в контексте непринятых в будущий стандарт концептов? Или что?

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

J>Ну уж точно это не будет иметь отношения к бизнес-задаче, до нее еще 15 этажей топать наверх.

Это просто спор о словах, то есть не о чём.


J>ОК. Про "слишком поздно" я написал. Про "слишком криво" — нет. Так что рассказывай.

Ну напиши, как сделать "не слишком поздно"...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[16]: Не понимаю...
От: jazzer Россия Skype: enerjazzer
Дата: 25.07.11 16:49
Оценка:
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, jazzer, Вы писали:


E>>>Ты утрируешь, возможно, что он тоже утрирует.

E>>>Фортран -- один из самых высокоуровневых языков, который я знаю. Ясен пень, что для своих задач, как и любой высокоуровневый язык.
J>>О да. 100500 параллельных массивов — это очень высокоуровнево.
E>Для вычматов фортран нереально удобен.
ну про "нереально" ты загнул, ИМХО.

J>>Ну это реализация шаблонов средствами Си (и Java до generics, кстати). Это все к вопросу о том, как люди жили до шаблонов.

E>Давай обсудим аду, там всякую с модулой?
Смысл? Народ на сях и Си-подобных языках пишет в основном. Ну и на Паскале/Бейсике в школе.

E>>>Ну это вообще косяк шаблонов в С++ такой. Да, они уроды. Тут ничего не попишешь.

J>>Где именно косяк?
E>1) И в каком месте в шаблонах С++ можно формально описать требования на параметры?
enable_if/static_assert. А так — концепты будут когда-нть.
E>2) И кто и как гарантирует, что требования исчерпывающие, кстати?
программер, вестимо. Это к чему вообще было? Ты еще спроси, кто программу пишет

E>В частности ТС сказал, что ему надо запретить параметру шаблона не быть наследником определённого класса. То есть, фактически, запретить утиниую типизацию. Так?

А, только и всего...

J>>Ты про уродство шаблонов говоришь в контексте непринятых в будущий стандарт концептов? Или что?

E>Я про шаблоны, как они есть сейчас. Возможно когда-то кто-то придумает что-то, что всех спасёт, но я не верю, что это изобретение будет продавлено через комитет
Чем тебя концепты не устраивают?

J>>Ну уж точно это не будет иметь отношения к бизнес-задаче, до нее еще 15 этажей топать наверх.

E>Это просто спор о словах, то есть не о чём.
Именно. Поэтому я и говорил, что это бессмысленный флейм.

J>>ОК. Про "слишком поздно" я написал. Про "слишком криво" — нет. Так что рассказывай.

E>Ну напиши, как сделать "не слишком поздно"...
enable_if. Я, правда, не знаю, что ты там вкладываешь в слово поздно, если "компилятор уже определился, какую функцию звать", то 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[17]: Не понимаю...
От: Erop Россия  
Дата: 25.07.11 18:57
Оценка:
Здравствуйте, jazzer, Вы писали:

E>>Для вычматов фортран нереально удобен.

J>ну про "нереально" ты загнул, ИМХО.
Зря ты так. Правда очень удобно всё. БЫСТРО и ПЕРЕНОСИМО!

J>>>...к вопросу о том, как люди жили до шаблонов.

E>>Давай обсудим аду, там всякую с модулой?
J>Смысл? Народ на сях и Си-подобных языках пишет в основном. Ну и на Паскале/Бейсике в школе.
Ну ты хотел обсудить, как люди жили до приплюснутых шаблонов же? По идее надо обсуждать кобол и алгол, но это очень давно было, можно начать с ады и модулы...

E>>1) И в каком месте в шаблонах С++ можно формально описать требования на параметры?

J>enable_if/static_assert.
1а) костыли
1б) Запиши-ка мне, что-нибудь вроде "только для перечислений", или "только для структур имеющих поля арифметических типов"
J>А так — концепты будут когда-нть.
Ну я уже сказал тебе, что я про это "будут когда-нибудь" думаю. И концепты были не слишком просты концептуально, и будут ли когда-нибудь -- тоже вопрос

E>>2) И кто и как гарантирует, что требования исчерпывающие, кстати?

J>программер, вестимо. Это к чему вообще было? Ты еще спроси, кто программу пишет
Ну, вот для функции можно требования на параметры, по крайней мере на их типы, описать формально. А для шаблона -- фиг вам там. Неужели ты не воспринимаешь это, как недостаток?

E>>В частности ТС сказал, что ему надо запретить параметру шаблона не быть наследником определённого класса. То есть, фактически, запретить утиниую типизацию. Так?

J>А, только и всего...

Ну, в целом да, ты всё время пытаешься вывести обсуждение куда-то в оффтопик

J>Чем тебя концепты не устраивают?

Например тем, что их нет.

J>>>Ну уж точно это не будет иметь отношения к бизнес-задаче, до нее еще 15 этажей топать наверх.

E>>Это просто спор о словах, то есть не о чём.
J>Именно. Поэтому я и говорил, что это бессмысленный флейм.
Ну так не надо его продолжать, называть ли истинные цели ТС "бизнес-уровнем" или как-то ещё.
Намного интереснее понять таки, зачем ТС понадобилось такое причудливое ограничение. Очень может быть, что ему нужен вовсе и не static_assert, а что-то совсем другое...

J>enable_if. Я, правда, не знаю, что ты там вкладываешь в слово поздно, если "компилятор уже определился, какую функцию звать", то enable_if отловит попытку вызова. Если что-то другое — расшифруй.


Ну этот ваш enable_if -- костыль. Может я не знаю, как им сейчас модно пользоваться, но если для того, чтобы функция
template<typename T> int countXXX( const T& xxx ) { тут чего-то считают и возвращают }
получила ограничение "только для таких T, которые выведены их класса myRoot" надо или портить возвращаемое значение, или вводить фейковый параметр, то это вот костыли и есть. Кстати, может быть я в чём-то не разобрался, но как бы тут помогли концепты?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[3]: Ограничение на тип аргумента шаблона
От: Erop Россия  
Дата: 25.07.11 19:00
Оценка:
Здравствуйте, jazzer, Вы писали:

J>
 
J>template<class T>
J>struct C3 { 
J>    int count; 
J>    C3() : count( -1 ) {} 
J>    static const char* name() { return "C3"; } 
J>};

E>>

J>http://ideone.com/SGPJv

J>Егор, напиши 150 раз: "Я не будут больше хакерить без нужды, когда есть очевидные решения!"

Как сломать бустовскую дурилку сам напишешь?..
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[18]: Не понимаю...
От: _nn_ www.nemerleweb.com
Дата: 25.07.11 19:22
Оценка: +1
Здравствуйте, Erop, Вы писали:

E>Ну этот ваш enable_if -- костыль. Может я не знаю, как им сейчас модно пользоваться, но если для того, чтобы функция
template<typename T> int countXXX( const T& xxx ) { тут чего-то считают и возвращают }
получила ограничение "только для таких T, которые выведены их класса myRoot" надо или портить возвращаемое значение, или вводить фейковый параметр, то это вот костыли и есть. Кстати, может быть я в чём-то не разобрался, но как бы тут помогли концепты?


Да, enable_if не сравним не с statif if от D и ,тем более, ни с макросами Nemerle .
Однако без него никак.

Возвращаемое значение не портится, как был int так и останется int.
Различие только при определении функции: http://ideone.com/QrjSS
typename enable_if<is_condition<T>, int>::type == int при is_condition<T>::value == true
.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[19]: Не понимаю...
От: Erop Россия  
Дата: 25.07.11 19:43
Оценка:
Здравствуйте, _nn_, Вы писали:

__>Однако без него никак.

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

__>Возвращаемое значение не портится, как был int так и останется int.

__>Различие только при определении функции: http://ideone.com/QrjSS
__>
typename enable_if<is_condition<T>, int>::type == int при is_condition<T>::value == true
.


Дык, значит, ничего не поменялось в лучшую сторону.
Ясно, что тип не портится, но читабельность этого крокодила зело сомнительная, особенно, если возвращаемый тип не int, а немного посложнее... Ну и не все компиляторы прожуют это дело, конечно...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[13]: Не понимаю...
От: Masterkent  
Дата: 25.07.11 19:49
Оценка:
jazzer:

E>>Если boost доступен, то да, нет.

J>Да даже если и недоступен

Что уже интересно, т.к. Boost легко скачать и при необходимости оттуда можно выдрать нужные компоненты.

J>enable_if — это три строчки, а static_assert вообще в новом стандарте уже.


Собственно, enable_if тоже в C++0x имеется, правда, смысла в нём особого не видно — alias template-ами пользоваться будет гораздо удобнее:

template <class B, class T = void>
    using enable_if = typename std::enable_if<B::value, T>::type;
template <bool b, class T = void>
    using enable_if_c = typename std::enable_if<b, T>::type;

template <class T>
    enable_if<std::is_base_of<IReferenceCounted, T>, boost::intrusive_ptr<T>>
        create_intrusive(T* t);
Re[20]: Не понимаю...
От: _nn_ www.nemerleweb.com
Дата: 25.07.11 19:56
Оценка:
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, _nn_, Вы писали:


__>>Однако без него никак.

E>Ну я это и называю "уродство шаблонов С++". Возможно мне стоит выбрать формулировку помягче, но как ты урода не назови...
Такой он наш любимый C++

__>>Возвращаемое значение не портится, как был int так и останется int.

__>>Различие только при определении функции: http://ideone.com/QrjSS
__>>
typename enable_if<is_condition<T>, int>::type == int при is_condition<T>::value == true
.


E>Дык, значит, ничего не поменялось в лучшую сторону.

E>Ясно, что тип не портится, но читабельность этого крокодила зело сомнительная, особенно, если возвращаемый тип не int, а немного посложнее... Ну и не все компиляторы прожуют это дело, конечно...


Таких уже все меньше и меньше, да и обходные пути всегда есть.

А вот реально читабельность портиться от вложенных enable_if.
И тут тоже не все потеряно: http://cbear.berlios.de/meta/if.hpp

template<class C1, class C2, class C3, class C4, class C5>
struct X:
    Meta::if_<C1, T1>::
    template else_if<C2, T2>::o::
    template elst_if<C3, T3>::o::
    template else_if<C4, T4>::o::
    template else_if<C5, T5>::o::    
    template else_<E>
{




P.S.
Реально удобной шаблонную магию не назовешь, но без нее бывает сложнее.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[4]: Ограничение на тип аргумента шаблона
От: jazzer Россия Skype: enerjazzer
Дата: 25.07.11 23:14
Оценка:
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, jazzer, Вы писали:


J>>
 
J>>template<class T>
J>>struct C3 { 
J>>    int count; 
J>>    C3() : count( -1 ) {} 
J>>    static const char* name() { return "C3"; } 
J>>};

E>>>

J>>http://ideone.com/SGPJv

J>>Егор, напиши 150 раз: "Я не будут больше хакерить без нужды, когда есть очевидные решения!"

E>Как сломать бустовскую дурилку сам напишешь?..

А кто здесь что ломает? Человек объявил просто шаблон и инстанцировал его рутом. Для своих целей. Он ни сном ни духом о твоих выкрутасах с пространствами имен.
Например, std::vector< root > — для него тоже эта твоя "спрятанная" функция найдется Это теперь называется сломать?

А так сломать все что угодно можно, конечно, если целенаправленно ломать:
namespace std { template <> struct vector<Test::root>{ int oops[1/0]}; }

Только это не твой случай
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[18]: Не понимаю...
От: jazzer Россия Skype: enerjazzer
Дата: 26.07.11 02:05
Оценка:
Здравствуйте, Erop, Вы писали:

E>>>Для вычматов фортран нереально удобен.

J>>ну про "нереально" ты загнул, ИМХО.
E>Зря ты так. Правда очень удобно всё. БЫСТРО и ПЕРЕНОСИМО!
Ага. И нечитабельно.
Фортран был одним из первых моих языков, сразу после бейсика и асма, я тогда даже Паскаля не видел, а о Си даже и не слышал.
И организация массива структур с 10 полями как 10 параллельных массивов для меня не была чем-то особенным, пока я не познакомился с Паскалем/Си, в которых были нормальные структуры.

E>Ну ты хотел обсудить, как люди жили до приплюснутых шаблонов же?

Вообще-то это ты хотел это обсудить:

Я, конечно, всё понимаю, но как же люди раньше-то жили?



E>>>1) И в каком месте в шаблонах С++ можно формально описать требования на параметры?

J>>enable_if/static_assert.
E>1а) костыли
в смысле что не встроены в язык? Так static_assert уже встроен.

E>1б) Запиши-ка мне, что-нибудь вроде "только для перечислений"

не поверишь — is_enum<T>

E>или "только для структур имеющих поля арифметических типов"

очень смешно. И причем тут шаблоны? В С++ вообще рефлексия очень ограниченная. Все, что эта рефлексия позволяет делать, можно использовать и в шаблонах. В крайнем случае — самописно через traits.

J>>А так — концепты будут когда-нть.

E>Ну я уже сказал тебе, что я про это "будут когда-нибудь" думаю. И концепты были не слишком просты концептуально, и будут ли когда-нибудь -- тоже вопрос
Не сложнее существующих шаблонов.

E>>>2) И кто и как гарантирует, что требования исчерпывающие, кстати?

J>>программер, вестимо. Это к чему вообще было? Ты еще спроси, кто программу пишет
E>Ну, вот для функции можно требования на параметры, по крайней мере на их типы, описать формально. А для шаблона -- фиг вам там. Неужели ты не воспринимаешь это, как недостаток?

Что такого можно описать формально у обычных функций, чего нельзя описать у шаблонов?
Обычные функции позволяют выразить ровно 1 требование: тип аргумента должен быть конвертируемым в тип параметра. А сюда попадает все подряд — и сам тип, и его наследники, и совершенно левые типы, которые могут быть в него сконвертированы, если у них есть соответствующий оператор преобразования...
Шаблоны представляют собой гораздо более точный и тонкий инструмент.

J>>Чем тебя концепты не устраивают?

E>Например тем, что их нет.
ОК, принято. Взамен есть enable_if/static_assert, а также Boost.ConceptCheck. Если ты против просто потому, что их нет в языке (static_assert уже есть), то так и говори.

E>Намного интереснее понять таки, зачем ТС понадобилось такое причудливое ограничение. Очень может быть, что ему нужен вовсе и не static_assert, а что-то совсем другое...

Зачем тебе это? Ну узнаешь ты, почему ему это надо, что-то изменится? Ему же все равно это надо
Мне вот такое ограничение тоже несколько раз было нужно в функции с несколькими дефолтными шаблонными аргументами.

J>>enable_if. Я, правда, не знаю, что ты там вкладываешь в слово поздно, если "компилятор уже определился, какую функцию звать", то enable_if отловит попытку вызова. Если что-то другое — расшифруй.


E>Ну этот ваш enable_if -- костыль. Может я не знаю, как им сейчас модно пользоваться, но если для того, чтобы функция
template<typename T> int countXXX( const T& xxx ) { тут чего-то считают и возвращают }
получила ограничение "только для таких T, которые выведены их класса myRoot" надо или портить возвращаемое значение, или вводить фейковый параметр, то это вот костыли и есть.

На это уже ответили. Если твое выступление сводится к тому, чтоб можно использовать только то, что есть непосредственно в языке, причем использовать только для того, для чего оно было изначально предназначено (нельзя пользоваться TMP, потому что шаблоны изначально делались для другого), то я твою позицию понимаю, хотя и не принимаю. Тем более что ты сам же ей и противоречишь своим "решением" с пространством имен, которые не предназначались для таких трюков.

E>Кстати, может быть я в чём-то не разобрался, но как бы тут помогли концепты?

Ты бы записал все свои ограничения на тип в виде концепта MyConstrainedType, а потом в объявлении функции вместо typename написал бы имя концепта:
template<MyConstrainedType T> int countXXX( const T& xxx )

Это слегка аналогично нынешним traits + enable_if< traits<T> >, но с прямой поддержкой компилятора и некоторыми дополнительными вкусностями (которые, впрочем, ограниченно доступны и сегодня, см. Boost.Range).
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[21]: Не понимаю...
От: Erop Россия  
Дата: 26.07.11 02:07
Оценка:
Здравствуйте, _nn_, Вы писали:


__>P.S.

__>Реально удобной шаблонную магию не назовешь, но без нее бывает сложнее.

Ну да. О том и речь, что во многих случаях можно так всё спроектировать С САМОГО НАЧАЛА, что магия не понадобится...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[19]: Не понимаю...
От: Erop Россия  
Дата: 26.07.11 02:36
Оценка:
Здравствуйте, jazzer, Вы писали:

E>>Зря ты так. Правда очень удобно всё. БЫСТРО и ПЕРЕНОСИМО!

J>Ага. И нечитабельно.
Наоборот, читабельно!
Просто класс задач, на которые ориентирован фортран довольно точно очерчен. Это вычматы.

J>И организация массива структур с 10 полями как 10 параллельных массивов для меня не была чем-то особенным, пока я не познакомился с Паскалем/Си, в которых были нормальные структуры.

На кой в вычматах структуры?


J>Вообще-то это ты хотел это обсудить:

J>

J>Я, конечно, всё понимаю, но как же люди раньше-то жили?

Ну так тогда давай обсуждать аду и модулу, раз уж я выбираю тему

E>>1а) костыли

J>в смысле что не встроены в язык? Так static_assert уже встроен.
В смысле неудобно.

E>>1б) Запиши-ка мне, что-нибудь вроде "только для перечислений"

J>не поверишь — is_enum<T>
Ну ещё один хак, гарантий работоспособности которого нет. Нету в С++ нормальных средств работы с параметрами шаблонов.

E>>или "только для структур имеющих поля арифметических типов"

J>очень смешно. И причем тут шаблоны? В С++ вообще рефлексия очень ограниченная. Все, что эта рефлексия позволяет делать, можно использовать и в шаблонах. В крайнем случае — самописно через traits.

Вот через traits да, можно. Именно это я и посоветовал ТС в качестве основного решения, если ты не заметил. Это один из немногих работоспособных подходов. Но он всё равно убогенький довольно.

О том и речь, что С++ шаблоны очень корявые. С одной стороны нет способов формально описать и прогарантировать интерфейс шаблона, а с другой практически нет способов работы с параметрами шаблона. IMHO, эти недостатки очевидны и объективны. Так что я предмет спора не очень вижу.

J>Не сложнее существующих шаблонов.

Беда в том, что существующие шаблоны сделаны из каких-то малопонятных соображений.
Их, конечно, хотели сделать так, "как удобнее компилятору", но потом придумали STL, и авторов компиляторов поставили раком. Теперь это неудобно ни компилятору, ни программисту. Но, вместо того, чтобы что-то с этим абсурдом сделать, ситуацию только ухудшают и запутывают...

J>Что такого можно описать формально у обычных функций, чего нельзя описать у шаблонов?

Блин, функция формально гарантирует свой интерфейс. То есть есть формальное, вполне таки проверяемое описание того, какие свойства параметров требуются для этой функции. Для шаблона нет способа задать такую границу.

J>ОК, принято. Взамен есть enable_if/static_assert, а также Boost.ConceptCheck. Если ты против просто потому, что их нет в языке (static_assert уже есть), то так и говори.

Я против, потому, что это неудобно, ограниченно переносимо, долго компилируется и всё равно ничего не гарантирует при этом.
Соответственно, если есть таки возможность спроектировать программу так, чтобы все эти чудеса не требовались, то оно может быть и к лучшему...
J>Зачем тебе это? Ну узнаешь ты, почему ему это надо, что-то изменится? Ему же все равно это надо
Ну может легко так оказаться, что ему надо что-то другое.


J>Мне вот такое ограничение тоже несколько раз было нужно в функции с несколькими дефолтными шаблонными аргументами.

А что такое дефолтные шаблонные аргументы функций?

J>На это уже ответили. Если твое выступление сводится к тому, чтоб можно использовать только то, что есть непосредственно в языке, причем использовать только для того, для чего оно было изначально предназначено (нельзя пользоваться TMP, потому что шаблоны изначально делались для другого), то я твою позицию понимаю, хотя и не принимаю. Тем более что ты сам же ей и противоречишь своим "решением" с пространством имен, которые не предназначались для таких трюков.


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

J>Это слегка аналогично нынешним traits + enable_if< traits<T> >, но с прямой поддержкой компилятора и некоторыми дополнительными вкусностями (которые, впрочем, ограниченно доступны и сегодня, см. Boost.Range).


Спасибо, понятно.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[20]: Не понимаю...
От: jazzer Россия Skype: enerjazzer
Дата: 26.07.11 03:34
Оценка:
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, jazzer, Вы писали:


E>>>Зря ты так. Правда очень удобно всё. БЫСТРО и ПЕРЕНОСИМО!

J>>Ага. И нечитабельно.
E>Наоборот, читабельно!
E>Просто класс задач, на которые ориентирован фортран довольно точно очерчен. Это вычматы.
ОК. Значит за пределами вычматов фортран "не нужен" и выбывает из дальнейшего обсуждения.

J>>И организация массива структур с 10 полями как 10 параллельных массивов для меня не была чем-то особенным, пока я не познакомился с Паскалем/Си, в которых были нормальные структуры.

E>На кой в вычматах структуры?
Ну здрасте. У тебя каждой точке сетки всего одно значение приписано? Не говоря уже о том, что в Fortran-90 они так были добавлены (правда, я его уже не застал):
   type ijk
      integer :: i
      integer :: j
      integer :: k
   end type ijk


E>Ну так тогда давай обсуждать аду и модулу, раз уж я выбираю тему

с кем-нть другим. У меня есть шаблоны в С++, и обсуждать методы кривокодинга в других языках мне неинтересно.

E>>>1а) костыли

J>>в смысле что не встроены в язык? Так static_assert уже встроен.
E>В смысле неудобно.
Ну так в С++ много чего неудобного, это ж не повод отказаться от использования всего этого.

E>>>1б) Запиши-ка мне, что-нибудь вроде "только для перечислений"

J>>не поверишь — is_enum<T>
E>Ну ещё один хак, гарантий работоспособности которого нет. Нету в С++ нормальных средств работы с параметрами шаблонов.
На всех нормальных компиляторах это работает

E>>>или "только для структур имеющих поля арифметических типов"

J>>очень смешно. И причем тут шаблоны? В С++ вообще рефлексия очень ограниченная. Все, что эта рефлексия позволяет делать, можно использовать и в шаблонах. В крайнем случае — самописно через traits.

E>Вот через traits да, можно. Именно это я и посоветовал ТС в качестве основного решения, если ты не заметил. Это один из немногих работоспособных подходов. Но он всё равно убогенький довольно.

Гы. А остальные посоветовали что-то другое? Ну и что же такое, по-твоему, traits? is_enum — это не traits, разве? А is_base_of? Да и вся библиотека Boost.TypeTraits: http://www.boost.org/libs/type_traits
Дальше — вот у тебя есть traits, как ты его будешь использоватьв своей функции?
Прямой способ — enable_if/static_assert.
Твой способ какой?

E>О том и речь, что С++ шаблоны очень корявые. С одной стороны нет способов формально описать и прогарантировать интерфейс шаблона, а с другой практически нет способов работы с параметрами шаблона. IMHO, эти недостатки очевидны и объективны. Так что я предмет спора не очень вижу.

Практически — как раз есть. Все высказавшиеся за static_assert/enable_if (включая меня) пользуются ими именно на практике, и все замечательно просто работает.

J>>Не сложнее существующих шаблонов.

E>Беда в том, что существующие шаблоны сделаны из каких-то малопонятных соображений.
А конкретнее? Из того, что я знаю, их сделали, чтоб можно было контейнеры писать не на макросах с void* внутри, как в Си.

E>Их, конечно, хотели сделать так, "как удобнее компилятору", но потом придумали STL, и авторов компиляторов поставили раком.

Это каким же образом STL ставить компилятор раком? Она же простая как бублик. Ладно б ты Boost.MPL привел в пример, но STL

E>Теперь это неудобно ни компилятору, ни программисту. Но, вместо того, чтобы что-то с этим абсурдом сделать, ситуацию только ухудшают и запутывают...

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

J>>Что такого можно описать формально у обычных функций, чего нельзя описать у шаблонов?

E>Блин, функция формально гарантирует свой интерфейс. То есть есть формальное, вполне таки проверяемое описание того, какие свойства параметров требуются для этой функции. Для шаблона нет способа задать такую границу.
Чем конкретно не устраивает enable_if? Только конкретно, а то одни общие слова.

J>>ОК, принято. Взамен есть enable_if/static_assert, а также Boost.ConceptCheck. Если ты против просто потому, что их нет в языке (static_assert уже есть), то так и говори.

E>Я против, потому, что это неудобно, ограниченно переносимо, долго компилируется и всё равно ничего не гарантирует при этом.
Пример, как она "ничего не гарантирует", в студию. А "неудобно" — это не аргумент, когда нет удобной альтернативы. Твоя алтернатива с пространствами имен — это не просто неудобно и неочевидно, это вообще леденящий душу.

E>Соответственно, если есть таки возможность спроектировать программу так, чтобы все эти чудеса не требовались, то оно может быть и к лучшему...

Если ты "к лучшему" называешь свой изврат с пространствами имен, то я прямо и не знаю, что тебе на это ответить...

J>>Зачем тебе это? Ну узнаешь ты, почему ему это надо, что-то изменится? Ему же все равно это надо

E>Ну может легко так оказаться, что ему надо что-то другое.
Ну тогда это будет другая задача.

J>>Мне вот такое ограничение тоже несколько раз было нужно в функции с несколькими дефолтными шаблонными аргументами.

E>А что такое дефолтные шаблонные аргументы функций?
Их эмуляция, очевидно.

J>>На это уже ответили. Если твое выступление сводится к тому, чтоб можно использовать только то, что есть непосредственно в языке, причем использовать только для того, для чего оно было изначально предназначено (нельзя пользоваться TMP, потому что шаблоны изначально делались для другого), то я твою позицию понимаю, хотя и не принимаю. Тем более что ты сам же ей и противоречишь своим "решением" с пространством имен, которые не предназначались для таких трюков.


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

Ну и с какой стати ты помещаешь root в Test, еcли потом тут же пишешь using? Какая такая архитектурная задача требует такого решения?
Ну и как насчет std::vector<root> заодно? Ты не по назначению их используешь здесь. Ты пользуешься побочным эффектом для влияния на алгорим поиска имени — это никому не понятное без дополнительных комментариев хакерство, которое к тому же еще и не работает.

E>Во-вторых, я вроде как понятно выразился, что мне не нравится. Дело не в том встроено там что-то в язык или нет, а в том, что неудобно всё, сложно и не очень хорошо работает. Это как на бильярде. Трюки люди забавные бьют, но когда играют мастера, то все удары в серии, кроме, быть может первого, на удивление простые и удобные почему-то.

"не очень хорошо работает" в студию. Я с таким не встречался. enable_if/static_assert + traits — никогда у меня с такой связкой проблем не было на протяжении многих лет уже.

Причем всё уже в новом стандарте, см. [dcl.dcl], [meta.trans.other] и [meta.type.synop].
Либо в бусте, для компиляторов, которые пока новый стандарт не поддерживают в этом объеме, а таких уже мало осталось, например, уже GCC 4.3 выпуска аж 2008 года все это поддерживает "из коробки" и буст ему не нужен.

J>>Это слегка аналогично нынешним traits + enable_if< traits<T> >, но с прямой поддержкой компилятора и некоторыми дополнительными вкусностями (которые, впрочем, ограниченно доступны и сегодня, см. Boost.Range).


E>Спасибо, понятно.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.