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

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

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

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

19.09.2012, 12:45. Просмотров 2300. Ответов 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
OhMyGodSoLong
~ Эврика! ~
1244 / 993 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
19.09.2012, 15:00 #31
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
- а зачем нам городить огород кода, как ты советуешь, м?(по длинне думаю выйдет не короче, а наверное и длинне чем моя простая реализация) ТС-у осталось лишь прописать все методы std::vector (нужные для его алгоритма, даже не все) в GybridContainer и юзать, вместо занятий бог весть чем...
static_assert без нормального вывода сообщения об ошибке, но успешно не дающий скомпилить программу, пишется на коленке в три строки, если уж так неохота тащить буст.
0
-=ЮрА=-
19.09.2012, 15:02
  #32

Не по теме:

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

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

Не по теме:

~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
19.09.2012, 15:17 #34

Не по теме:

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



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

Не по теме:

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

0
ForEveR
В астрале
Эксперт С++
7983 / 4742 / 321
Регистрация: 24.06.2010
Сообщений: 10,547
Завершенные тесты: 3
19.09.2012, 15:21 #35
-=ЮрА=-, У него static_assert написан именно в 3 строки. Остальное тесты.
0
OhMyGodSoLong
~ Эврика! ~
1244 / 993 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
19.09.2012, 15:23 #36
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Я обещал технически работающий 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
John Prick
824 / 757 / 152
Регистрация: 27.07.2012
Сообщений: 2,156
Завершенные тесты: 3
19.09.2012, 15:25 #37
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
Пока решения кроме своего из поста 24 я так и не увидел
Ну если не смотреть, то и не увидишь.
0
FireNovel
150 / 73 / 8
Регистрация: 09.04.2010
Сообщений: 297
19.09.2012, 15:39  [ТС] #38
Я смотрю тут такая дискуссия... Мне прям стыдно влезать с вопросом

Может я некорректно поставил предыдущий вопрос, поэтому перефразирую.
Необходимо наличие определенного метода в допустимых типах
например допустимые типы: 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
John Prick
824 / 757 / 152
Регистрация: 27.07.2012
Сообщений: 2,156
Завершенные тесты: 3
19.09.2012, 15:45 #39
Цитата Сообщение от FireNovel Посмотреть сообщение
// хотелось бы чтобы MyVec работал только с теми типами
// в которых есть метод Calc()
Ну так он и будет только с ними работать. Со всеми другими будет выдаваться ошибка компиляции, говорящая о том, что метода Calc в классе, переданном в MyVec, нет. И ничего лишнего городить не надо.
0
DU
1484 / 1130 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
19.09.2012, 15:45 #40
как уже писали, при наличии статик ассерта и другой оснастки, написать такое достаточно просто.
за деталями обнаружения метода отсылаю к саттеру. у него есть главы, посвященные этому.

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
ForEveR
В астрале
Эксперт С++
7983 / 4742 / 321
Регистрация: 24.06.2010
Сообщений: 10,547
Завершенные тесты: 3
19.09.2012, 16:35 #41
Как-то так если с относительно понятными ошибками.

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
template<bool>
struct CompileCheck { CompileCheck(...); };
 
template<>
struct CompileCheck<false>
{
};
 
#define STATIC_ASSERT(value, message) \
class ERROR_##message { };\
enum { _##message = sizeof((CompileCheck<(value) != 0>(ERROR_##message()))) };
 
template<typename T, typename U>
struct is_same
{
   static const bool value = false;
};
 
template<typename T>
struct is_same<T, T>
{
   static const bool value = true;
};
 
template<typename T>
class Vector
{
  STATIC_ASSERT((is_same<T, double>::value || is_same<T, int>::value), INT_AND_DOUBLE_ONLY)
};
 
int main()
{
   Vector<int> v;
   Vector<long> vv;
}
static_assert взят почти целиком из Александреску
1
CheshireCat
Эксперт С++
2896 / 1245 / 78
Регистрация: 27.05.2008
Сообщений: 3,405
19.09.2012, 17:04 #42
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Можно еще и потребовать, чтобы в классе обязательно была реализована определенная функция:
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include <iostream>
using namespace std;
 
template<bool>
struct CompileCheck { CompileCheck(...); };
 
template<>
struct CompileCheck<false>
{
};
 
#define STATIC_ASSERT(value, message) \
class ERROR_##message { };\
enum { _##message = sizeof((CompileCheck<(value) != 0>(ERROR_##message()))) };
 
template<typename T, typename U>
struct is_same
{
   static const bool value = false;
};
 
template<typename T>
struct is_same<T, T>
{
   static const bool value = true;
};
 
template<class T> struct has_member_Func;
 
template<class R, class C> class has_member_Func<R C::*>
{
    template<R C::*> struct helper;
    template<class T> static char check(helper<&T::Func>*);
    template<class T> static char (&check(...))[2];
public:
    enum { value = sizeof(check<C>(0)) == 1 };
};
 
// Тестовые классы:
 
class A
{
};
 
class B
{
public:
    void Func(B&);
};
 
struct C
{
public:
    void AnotherFunc(C&);
};
 
 
int main()
{
    STATIC_ASSERT(has_member_Func<void (A::*)(A&)>::value, CLASS_A_HASNT_MEMBER_FUNCTION_FUNC);
    STATIC_ASSERT(has_member_Func<void (B::*)(B&)>::value, CLASS_B_HASNT_MEMBER_FUNCTION_FUNC);
    STATIC_ASSERT(has_member_Func<void (C::*)(C&)>::value, CLASS_C_HASNT_MEMBER_FUNCTION_FUNC);
    return 0;
}
6
19.09.2012, 17:04
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.09.2012, 17:04
Привет! Вот еще темы с ответами:

Ошибка компиляции: 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; ...


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

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

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