Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.57/21: Рейтинг темы: голосов - 21, средняя оценка - 4.57
 Аватар для FireNovel
150 / 73 / 27
Регистрация: 09.04.2010
Сообщений: 297

Шаблоны template с ограниченными параметрами

19.09.2012, 12:45. Показов 4945. Ответов 41
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Привет всем. У меня короткий вопрос.
например есть такой код:
C++
1
2
3
4
template <class T>
class MyVec {
    std::vector<T> m_vec;
};
Возможно ли сделать так чтобы MyVec работал только с определенными классами.
То есть, параметр шаблона T мог принимать только определенные мною значения (например MyClass1, int и всё, другие нельзя).
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
19.09.2012, 12:45
Ответы с готовыми решениями:

«Шаблоны шаблонов» vs «шаблоны с параметрами-шаблонами».
«Шаблоны шаблонов» vs «шаблоны с параметрами-шаблонами». Есть ли разница в этих понятиях? Если есть, то в чём? И где (в каких...

Как вы применяете шаблоны template в C++?
Доброе утро! В C#, которым пользуюсь, есть возможность подстановки типа в класс. В C++ есть более широкое понятие о шаблонах. Какие есть...

Шаблоны типа template<class T*>
Здравствуйте, объясните пожалуйста, что означает сия запись: template&lt;class T*&gt;. И означает ли она, что я далее смогу использовать только...

41
19.09.2012, 14:46
Студворк — интернет-сервис помощи студентам

Не по теме:

А. Ну да. John Prick, извините

0
19.09.2012, 14:48

Не по теме:

Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
Не вопрос надо так надо - выше простой пример. Я зуб за 100 даю задание ТС решается куда более проще если узнать зачем оно надо, буз всяких шаблонов и прочего высокоуровневого кода, просто люди часто сами себе проблем придумают а потом решают...
Это проблема более высокого уровня. Нельзя и на ёлку влезть (статически гарантируемый тайпсейф) и жопу не ободрать (вагон кода сверху для описания типов). Особенно в Си++, где типы описывать можно только шаблонной магией и нет удобного способа описать тип "это может быть int, double или bool".

2
Эксперт С++
2924 / 1274 / 114
Регистрация: 27.05.2008
Сообщений: 3,465
19.09.2012, 14:48
FireNovel, грамотное решение тебе предложил коллега ForEveR. О списках типов и static_assert хорошо написано у Александреску в его "Современном проектировании на C++" (книга существует в электронном виде в Сети, гугл в помощь).
1
Автор FAQ
 Аватар для -=ЮрА=-
6614 / 4256 / 401
Регистрация: 08.08.2009
Сообщений: 10,325
Записей в блоге: 24
19.09.2012, 14:48
Так! Меня начинает напрягать глупость некоторых, вот код который позволяет добавлять только int и double что с ним делать пусть ТС решает, единственное ему вместо
C++
1
typeid(val) == typeid(double)
следет записать
C++
1
typeid(val) == typeid(MyClass1)
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <vector>
#include <iostream>
using namespace std;
 
template <class T>
class GybridContainer
{
private:
    vector<T> vec;
    //typedef vector<T>::iterator iterator;
public:
    GybridContainer(){vec.clear();}
    void push_back(T val)
    {
        if
        (
            typeid(val) == typeid(double)
            ||
            typeid(val) == typeid(int)
        )
        {
            cout<<val<<" is added"<<endl;
            vec.push_back(val);
        }
        else
            cout<<val<<" not added"<<endl;
    }
    T at(int i)
    {
        return vec.at(i);
    }
};
 
int main()
{
    int i;
    GybridContainer<int> pInt;
    for(i = 0; i < 20; i++)
        pInt.push_back(i);
    GybridContainer<double> pDbl;
    for(i = 0; i < 20; i++)
        pDbl.push_back(1.0*i);
    GybridContainer<char> pChr;
    for(i = 0; i < 20; i++)
        pChr.push_back((char)(i + 48));
    return 0;
}
Отработка здесь http://codepad.org/PJKqWgze
и под катом
Отработка
0 is added
1 is added
2 is added
3 is added
4 is added
5 is added
6 is added
7 is added
8 is added
9 is added
10 is added
11 is added
12 is added
13 is added
14 is added
15 is added
16 is added
17 is added
18 is added
19 is added
0 is added
1 is added
2 is added
3 is added
4 is added
5 is added
6 is added
7 is added
8 is added
9 is added
10 is added
11 is added
12 is added
13 is added
14 is added
15 is added
16 is added
17 is added
18 is added
19 is added
0 not added
1 not added
2 not added
3 not added
4 not added
5 not added
6 not added
7 not added
8 not added
9 not added
: not added
; not added
< not added
= not added
> not added
? not added
@ not added
A not added
B not added
C not added
Press any key to continue


PS:Кто не умеет писать просто - тот не умеет писать вооюще, Удачи!
0
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
19.09.2012, 14:50
-=ЮрА=-, И зачем нам проверка в runtime?)
0
~ Эврика! ~
 Аватар для OhMyGodSoLong
1258 / 1007 / 74
Регистрация: 24.07.2012
Сообщений: 2,002
19.09.2012, 14:50
Юра, это динамическая проверка. А надо именно статически, в этом и вся соль.


Цитата Сообщение от ForEveR Посмотреть сообщение
soon, Нет. Юра предлагал два класса. Различных. О специализации Юра не говорил.
А какая разница? Методы всё равно придётся дублировать, они ж не наследуются специализациями.
0
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
19.09.2012, 14:53
~OhMyGodSoLong~, Так-то да. Но будет одно имя для типа. Специализация столь же тяжела, сколь и описание типов с разными именами (по кол-ву кода).
0
Автор FAQ
 Аватар для -=ЮрА=-
6614 / 4256 / 401
Регистрация: 08.08.2009
Сообщений: 10,325
Записей в блоге: 24
19.09.2012, 14:56
Цитата Сообщение от ForEveR Посмотреть сообщение
-=ЮрА=-, И зачем нам проверка в runtime?)
- а зачем нам городить огород кода, как ты советуешь, м?(по длинне думаю выйдет не короче, а наверное и длинне чем моя простая реализация) ТС-у осталось лишь прописать все методы std::vector (нужные для его алгоритма, даже не все) в GybridContainer и юзать, вместо занятий бог весть чем...

Не по теме:

А самое смешное, автор темы явно указал рамки в которых необходимо решение

Цитата Сообщение от FireNovel Посмотреть сообщение
Блин. Я в VS2008 пишу
. Ну вот у меня решение готово, а у тебя каким оно будет?

0
2395 / 1924 / 763
Регистрация: 27.07.2012
Сообщений: 5,569
19.09.2012, 14:58
Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
Методы всё равно придётся дублировать, они ж не наследуются специализациями.
Ну кстати, можно ведь контейнер спрятать в отдельный класс.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
template <class T>
struct ContainerWrapper;
 
template <>
struct ContainerWrapper<int>
{
   typedef std::vector<int> TContainer;
};
 
template <>
struct ContainerWrapper<MyClass>
{
   typedef std::vector<MyClass> TContainer;
};
 
template <class T>
class MyVec
{
   ContainerWrapper<T>::TContainer;
};
Тогда код MyVec дублировать не придётся, а если использовать MyVec с каким-либо типом, отличным от int и MyClass, то отвалится на компиляции.
Решение, конечно, кривое, но уже не так плохо, как дублирование целого класса.
0
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
19.09.2012, 14:59
-=ЮрА=-, Использую стороннюю библиотеку (буст, локи).) Можно и самому написать, но это лень.
0
~ Эврика! ~
 Аватар для OhMyGodSoLong
1258 / 1007 / 74
Регистрация: 24.07.2012
Сообщений: 2,002
19.09.2012, 15:00
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
- а зачем нам городить огород кода, как ты советуешь, м?(по длинне думаю выйдет не короче, а наверное и длинне чем моя простая реализация) ТС-у осталось лишь прописать все методы std::vector (нужные для его алгоритма, даже не все) в GybridContainer и юзать, вместо занятий бог весть чем...
static_assert без нормального вывода сообщения об ошибке, но успешно не дающий скомпилить программу, пишется на коленке в три строки, если уж так неохота тащить буст.
0
19.09.2012, 15:02

Не по теме:

~OhMyGodSoLong~, ну возьми напиши автор темы тебе будет благодарен. Пока решения кроме своего из поста 24 я так и не увидел:)Меньше слов, больше действий;)

0
~ Эврика! ~
 Аватар для OhMyGodSoLong
1258 / 1007 / 74
Регистрация: 24.07.2012
Сообщений: 2,002
19.09.2012, 15:11
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение

Не по теме:

~OhMyGodSoLong~, ну возьми напиши автор темы тебе будет благодарен. Пока решения кроме своего из поста 24 я так и не увидел:)Меньше слов, больше действий;)

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
template <bool clause> struct static_assert__;
template <> struct static_assert__<true> {};
#define STATIC_ASSERT(clause) enum {___ = sizeof(static_assert__<(bool)(clause)>)}
 
class Foo {
  STATIC_ASSERT(1 == 2);
};
 
int foo()
{
  STATIC_ASSERT(1 == 2);
}
 
int main()
{
  STATIC_ASSERT(1 == 2);
}
Недостатки: нехорошее сообщение об ошибке и только одна штука на локальную область видимости (плюс засирание этой области идентификатором ___).

Штуку type_equals<T1, T2>, которая true для равных и false для различных типов уж сами напишете.
0
Автор FAQ
 Аватар для -=ЮрА=-
6614 / 4256 / 401
Регистрация: 08.08.2009
Сообщений: 10,325
Записей в блоге: 24
19.09.2012, 15:17

Не по теме:

~OhMyGodSoLong~, ты уж прости "меня тупого", но каким гаком это всё относится к коду автора темы?Я пока ничего из твоего кода не уловил...
Где тут проверка на MyClass1 int - х*рня какая-то прости за выражение...
Вобщем ~OhMyGodSoLong~, я хочу увидеть готовый алгоритм с длинной кода хотя бы меньше моего, пока я ничего не вижу;)



Добавлено через 1 минуту

Не по теме:

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

0
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
19.09.2012, 15:21
-=ЮрА=-, У него static_assert написан именно в 3 строки. Остальное тесты.
0
~ Эврика! ~
 Аватар для OhMyGodSoLong
1258 / 1007 / 74
Регистрация: 24.07.2012
Сообщений: 2,002
19.09.2012, 15:23
Лучший ответ Сообщение было отмечено как решение

Решение

Я обещал технически работающий static_assert в три строки — я его показал.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
template <bool clause> struct static_assert__;
template <> struct static_assert__<true> {};
#define STATIC_ASSERT(clause) enum {___ = sizeof(static_assert__<(bool)(clause)>)}
 
template <typename T1, typename T2>
struct type_equals__ {
  static const bool value = false;
};
 
template <typename T>
struct type_equals__<T, T> {
  static const bool value = true;
};
 
#define TYPE_EQUALS(T1, T2) (type_equals__<T1, T2>::value)
 
template <class T>
class Foo {
  STATIC_ASSERT(TYPE_EQUALS(T, int) || TYPE_EQUALS(T, double));
  
  // ...
};
 
int main()
{
  Foo<int> ();
  Foo<double> ();
  Foo<char> ();
}
3
2395 / 1924 / 763
Регистрация: 27.07.2012
Сообщений: 5,569
19.09.2012, 15:25
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
Пока решения кроме своего из поста 24 я так и не увидел
Ну если не смотреть, то и не увидишь.
0
 Аватар для FireNovel
150 / 73 / 27
Регистрация: 09.04.2010
Сообщений: 297
19.09.2012, 15:39  [ТС]
Я смотрю тут такая дискуссия... Мне прям стыдно влезать с вопросом

Может я некорректно поставил предыдущий вопрос, поэтому перефразирую.
Необходимо наличие определенного метода в допустимых типах
например допустимые типы: Type1, Type2, Type3 ... (сразу уточню, что типы не стандартные)
Они должны содержать метод например Calc(). пока, что реализовал как писал ранее(с template). и все работает.
Но хотелось защитить от недопустимых типов, так как планирую расширять количество классов Type.

Может быть можно с помощью наследования решить
для Type Взять родителем абстрактный класс Base, но пока не придумал как.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class Type1 {   
    ...
public:
    double Calc() {}
};
 
class Type2{
    ...
public:
    double Calc() {}
};
 
 
class Base {
public:
    virtual double Calc() = 0;
};
 
template <class T>
class MyVec {
    std::vector<T> m_vec;
    ...
    double AllCalc(){
        for(int i = 0; i < m_vec.size(); ++i)
            m_vec[i].Calc(); // хотелось бы чтобы MyVec работал только с теми типами
                         // в которых есть метод Calc()
    }
};
~OhMyGodSoLong~, Спасибо надо будет изучить.
0
2395 / 1924 / 763
Регистрация: 27.07.2012
Сообщений: 5,569
19.09.2012, 15:45
Цитата Сообщение от FireNovel Посмотреть сообщение
// хотелось бы чтобы MyVec работал только с теми типами
// в которых есть метод Calc()
Ну так он и будет только с ними работать. Со всеми другими будет выдаваться ошибка компиляции, говорящая о том, что метода Calc в классе, переданном в MyVec, нет. И ничего лишнего городить не надо.
0
DU
1500 / 1146 / 165
Регистрация: 05.12.2011
Сообщений: 2,279
19.09.2012, 15:45
как уже писали, при наличии статик ассерта и другой оснастки, написать такое достаточно просто.
за деталями обнаружения метода отсылаю к саттеру. у него есть главы, посвященные этому.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
template <typename T1, typename T2>
struct is_same
{
  static const bool result = false;
};
 
template <typename T>
struct is_same<T, T>
{
  static const bool result = true;
};
 
 
template <typename T>
class Class
{
  template <typename U>
  struct check_method_existance
  {
    static bool result = true; // вот тут нужно имплементить. посмотреть можно у саттера или александревску.
  };
 
  template <typename U>
  struct validate_type
  {
    // набор проверок для типа сливается в одну переменную
    static const bool result = is_same<U, int>::result
                            || is_same<U, double>::result
                            || check_method_existance<U>::result
                            ;
  };
 
  STATIC_ASSERT(validate_type<T>::result);
 
public:
  Class()
  {
  }
};
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
19.09.2012, 15:45
Помогаю со студенческими работами здесь

подскажите template<class> (Шаблоны и указатели)
circl.h #ifndef _CIRCL_H #define _CIRCL_H template &lt;class t&gt; class circl{ private: circl *pNext,*pBack; public: t...

Что за пустые шаблоны template <> struct/inline?
что за пустые шаблоны template &lt;&gt; за которыми следуют class/struct/inline? По многочисленным источникам в c++ шаблоны имеют вид,...

Шаблоны: ошибки: requires template argument list или undeclared identifier
Есть маленький тестовый проект из 4-файлов. Что мне надо - рассказывать словами замучаюсь, взляните пожалуйста на код по ссылке ниже (он...

Genfit() с ограниченными параметрами
Здравствуйте, я пытаюсь фитировать экпериментальные точки к некой фукнции с помощью genfit(). Эта функция зависит от нескольких параметров...

Template Toolkit шаблоны
Всем привет я новичек в Perl, поэтому вопрос может быть довольно глупый, не отсылайте плиз читать мануалы) вот код из русской...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Видеокарта простаивает ночами? Вот 4 проекта, которые загрузят её наукой
Programma_Boinc 10.04.2026
Видеокарта простаивает ночами? Вот 4 проекта, которые загрузят её наукой Если на Windows стоит дискретная NVIDIA или AMD — можно отдать её вычислительную мощность реальным исследованиям. . . .
Очистка реквизитов документа при копировании
Maks 09.04.2026
Алгоритм из решения ниже применим как для типовых, так и для нетиповых документов на самых различных конфигурациях. Задача: при копировании документа очищать определенные реквизиты и табличную. . .
модель ЗдравоСохранения 8. Подготовка к разному выполнению заданий
anaschu 08.04.2026
https:/ / github. com/ shumilovas/ med2. git main ветка * содержимое блока дэлэй из старой модели теперь внутри зайца новой модели 8ATzM_2aurI
Блокировка документа от изменений, если он открыт у другого пользователя
Maks 08.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа, разработанного в конфигурации КА2. Задача: запретить редактирование документа, если он открыт у другого пользователя. / / . . .
Система безопасности+живучести для сервера-слоя интернета (сети). Двойная привязка.
Hrethgir 08.04.2026
Далее были размышления о системе безопасности. Сообщения с наклонным текстом - мои. А как нам будет можно проверить, что ссылка наша, а не подделана хулиганами, которая выбросит на другую ветку и. . .
Модель ЗдрввоСохранения 7: больше работников, больше ресурсов.
anaschu 08.04.2026
работников и заданий может быть сколько угодно, но настроено всё так, что используется пока что только 20% kYBz3eJf3jQ
Дальние перспективы сервера - слоя сети с космологическим дизайном интефейса карты и логики.
Hrethgir 07.04.2026
Дальнейшее ближайшее планирование вывело к размышлениям над дальними перспективами. И вот тут может быть даже будут нужны оценки специалистов, так как в дальних перспективах всё может очень сильно. . .
Горе от ума
kumehtar 07.04.2026
Эта мне ментальная установка, что вот прямо сейчас, мол, мне для полного счастья не хватает (нужное вписать), и когда я этого достигну - тогда и полный кайф. Одна из самых сильных ловушек на пути. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru