Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 17, средняя оценка - 4.88
FireNovel
150 / 73 / 8
Регистрация: 09.04.2010
Сообщений: 297
#1

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

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

Привет всем. У меня короткий вопрос.
например есть такой код:
C++
1
2
3
4
template <class T>
class MyVec {
    std::vector<T> m_vec;
};
Возможно ли сделать так чтобы MyVec работал только с определенными классами.
То есть, параметр шаблона T мог принимать только определенные мною значения (например MyClass1, int и всё, другие нельзя).
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
19.09.2012, 12:45
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Шаблоны template с ограниченными параметрами (C++):

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

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

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

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

Ошибки: 1) use of class template requires template argument list 2) 'T' : undeclared identifier - C++
Решил подправить свой класс с использованием шаблонов, но столкнулся со следующим косяком. Если я прописываю тело функций внутри описания...

'MyQueue' : use of class template requires template argument list - C++
Написал код про шаблоны. Не могу понять почему выводит ошибку во время наследования класса. ошибки 'MyQueue' : use of class template...

41
defer
19.09.2012, 14:32     Шаблоны template с ограниченными параметрами
  #16

Не по теме:

У меня дежавю???????

0
ForEveR
В астрале
Эксперт С++
7983 / 4742 / 321
Регистрация: 24.06.2010
Сообщений: 10,547
Завершенные тесты: 3
19.09.2012, 14:37 #17
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
-=ЮрА=-, Правда? Не секрет ведь, что std::sort работает исключительно с RA итераторами. Используя к примеру для списка - получаем ошибку компиляции. К примеру в gcc это работает так
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
  template<typename _RandomAccessIterator, typename _Compare>
    inline void
    sort(_RandomAccessIterator __first, _RandomAccessIterator __last,
     _Compare __comp)
    {
      typedef typename iterator_traits<_RandomAccessIterator>::value_type
    _ValueType;
 
      // concept requirements
      __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
        _RandomAccessIterator>)
      __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, _ValueType,
                  _ValueType>)
      __glibcxx_requires_valid_range(__first, __last);
Оп. Концепты. В VS работает примерно так же.

tuple.

C++
1
2
3
4
5
6
      template<typename... _UElements, typename = typename
           std::enable_if<sizeof...(_UElements)
                  == sizeof...(_Elements)>::type>
        explicit
        tuple(_UElements&&... __elements)
    : _Inherited(std::forward<_UElements>(__elements)...) { }
Будет принимать участие в выборе перегрузки только в том случае, если размеры списков типов - равны.

Не нужны, правда?
3
John Prick
821 / 754 / 152
Регистрация: 27.07.2012
Сообщений: 2,147
Завершенные тесты: 3
19.09.2012, 14:41 #18
если в лом качать boost, писать static_assert и прочее, можно поступить так:
C++
1
2
3
4
5
6
7
8
9
10
template <class T>
class MyVec;
 
template <>
class MyVec<int>
{ std::vector<int> my_vec; }
 
template <>
class MyVec<MyClass>
{ std::vector<MyClass> my_vec; }
Но опять же со всеми проблемами дублирования кода и жуткой нерасширяемости.

Поэтому самое красивое решение - список типов с нужным набором типов и static_assert на проверку совпадения каждого типа в списке шаблонному параметру.
0
soon
19.09.2012, 14:43
  #19

Не по теме:


если в лом качать boost, писать static_assert и прочее, можно поступить так:
John Prick, -=ЮрА=- это и предлагал

0
ForEveR
В астрале
Эксперт С++
7983 / 4742 / 321
Регистрация: 24.06.2010
Сообщений: 10,547
Завершенные тесты: 3
19.09.2012, 14:43 #20
soon, Нет. Юра предлагал два класса. Различных. О специализации Юра не говорил.
1
soon
19.09.2012, 14:46
  #21

Не по теме:

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

0
OhMyGodSoLong
19.09.2012, 14:48
  #22

Не по теме:

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

2
CheshireCat
Эксперт С++
2896 / 1245 / 78
Регистрация: 27.05.2008
Сообщений: 3,404
19.09.2012, 14:48 #23
FireNovel, грамотное решение тебе предложил коллега ForEveR. О списках типов и static_assert хорошо написано у Александреску в его "Современном проектировании на C++" (книга существует в электронном виде в Сети, гугл в помощь).
1
-=ЮрА=-
Заблокирован
Автор FAQ
19.09.2012, 14:48 #24
Так! Меня начинает напрягать глупость некоторых, вот код который позволяет добавлять только 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
В астрале
Эксперт С++
7983 / 4742 / 321
Регистрация: 24.06.2010
Сообщений: 10,547
Завершенные тесты: 3
19.09.2012, 14:50 #25
-=ЮрА=-, И зачем нам проверка в runtime?)
0
OhMyGodSoLong
~ Эврика! ~
1244 / 993 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
19.09.2012, 14:50 #26
Юра, это динамическая проверка. А надо именно статически, в этом и вся соль.


Цитата Сообщение от ForEveR Посмотреть сообщение
soon, Нет. Юра предлагал два класса. Различных. О специализации Юра не говорил.
А какая разница? Методы всё равно придётся дублировать, они ж не наследуются специализациями.
0
ForEveR
В астрале
Эксперт С++
7983 / 4742 / 321
Регистрация: 24.06.2010
Сообщений: 10,547
Завершенные тесты: 3
19.09.2012, 14:53 #27
~OhMyGodSoLong~, Так-то да. Но будет одно имя для типа. Специализация столь же тяжела, сколь и описание типов с разными именами (по кол-ву кода).
0
-=ЮрА=-
Заблокирован
Автор FAQ
19.09.2012, 14:56 #28
Цитата Сообщение от ForEveR Посмотреть сообщение
-=ЮрА=-, И зачем нам проверка в runtime?)
- а зачем нам городить огород кода, как ты советуешь, м?(по длинне думаю выйдет не короче, а наверное и длинне чем моя простая реализация) ТС-у осталось лишь прописать все методы std::vector (нужные для его алгоритма, даже не все) в GybridContainer и юзать, вместо занятий бог весть чем...

Не по теме:

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

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

0
John Prick
821 / 754 / 152
Регистрация: 27.07.2012
Сообщений: 2,147
Завершенные тесты: 3
19.09.2012, 14:58 #29
Цитата Сообщение от ~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
В астрале
Эксперт С++
7983 / 4742 / 321
Регистрация: 24.06.2010
Сообщений: 10,547
Завершенные тесты: 3
19.09.2012, 14:59 #30
-=ЮрА=-, Использую стороннюю библиотеку (буст, локи).) Можно и самому написать, но это лень.
0
19.09.2012, 14:59
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.09.2012, 14:59
Привет! Вот еще темы с ответами:

Ошибка компиляции: template-id does not match any template declaration - C++
Здравствуйте. Помогите, пожалуйста: #include &lt;iostream&gt; using namespace std; template &lt;typename T&gt; T maxn(T*, const int*); ...

В чем различие template <typename T> от template <class T> ? - C++
Добрый день ! Заметил в новых книгах применение записи template &lt;typename T&gt; вместо template &lt;class T&gt; в чем же тогда фишка...

Visual Studio выдаёт ошибку при вынесении объявления функции с template в .h файл. Без template всё работает - C++
Проект содержит три файла: Source.cpp, arrTreat.h, arrTreat.cpp. Source.cpp: #include &lt;iostream&gt; using std::cout; using...

MSVC и template template classes - C++
Приветствую. Как в MSVC передать template template класс? Простой пример template&lt;template&lt;typename, typename&gt; class Return&gt; ...


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

Или воспользуйтесь поиском по форуму:
30
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.