Форум программистов, компьютерный форум, киберфорум
C++
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.81/21: Рейтинг темы: голосов - 21, средняя оценка - 4.81
Неэпический
17870 / 10635 / 2054
Регистрация: 27.09.2012
Сообщений: 26,736
Записей в блоге: 1
1

Применение is_same для списка типов

01.02.2016, 03:16. Показов 3867. Ответов 17
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Итак, std::is_same может сравнить только два типа.
Написал велосипед,
который сравнивает первый тип со всеми остальными.
Собственно, вот код:
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#include <type_traits>
 
 
// =========================================================================================================
// ================================================is_same_list=============================================
// =========================================================================================================
 
 
namespace detail
{
 
 
 
struct is_same_list_impl
{
    template<
        template<bool,bool> class LogicTemplate,
        typename SameType,
        typename FirstType,
        typename ... Args
    >
    static
    constexpr std::enable_if_t<sizeof...(Args)!=0,bool>
    constexpr_call()
    {
        return
                LogicTemplate<
                    std::is_same<
                        SameType,
                        FirstType
                    >::value,
                    constexpr_call<LogicTemplate, SameType, Args...>()
                >::value ;
    }
 
 
 
    template<
        template<bool,bool> class LogicTemplate,
        typename SameType,
        typename FirstType,
        typename ... Args
    >
    static
    constexpr std::enable_if_t<sizeof...(Args)==0,bool>
    constexpr_call()
    {
        return
                std::is_same<
                    SameType,
                    FirstType
                >::value ;
    }
};
 
 
 
 
 
}//end of detail
 
 
 
 
namespace compile_time
{
    template<bool First, bool Second>
    struct constexpr_logical_and
    {
        static constexpr bool value = First && Second ;
    };
 
 
    template<bool First, bool Second>
    struct constexpr_logical_or
    {
        static constexpr bool value = First || Second ;
    };
}//end of compile_time
 
 
 
template<typename First, typename Second>
struct is_same_decay
{
    static constexpr bool value =
            std::is_same<
                std::decay_t<First>,
                std::decay_t<Second>
            >::value ;
};
 
 
template<typename SameType, typename ... Args>
struct is_all_same
{
    static constexpr bool value =
            detail::is_same_list_impl::constexpr_call<
                compile_time::constexpr_logical_and,
                SameType, Args...
            >() ;
};
 
 
template<typename SameType, typename ... Args>
struct is_one_same
{
    static constexpr bool value =
            detail::is_same_list_impl::constexpr_call<
                compile_time::constexpr_logical_or,
                SameType, Args...
            >() ;
};
 
 
 
 
 
// =========================================================================================================
// =========================================================================================================
// =========================================================================================================
is_one_same - определяет, есть ли в списке параметров хоть один тип, одинаковый с первым в списке,
т.е. false, если все типы отличны от первого, true - во всех остальных случаях.
is_all_same - определяет, все ли типы в списке одинаковые,
т.е. true, если все типы соответствуют первому, false - во всех остальных случаях.



Пример использования:
C++
1
2
3
4
5
6
7
8
9
10
int main(int argc, char ** argv)
{
    std::cout << is_all_same<int,int,float,double,int&>::value << std::endl ; //false
    std::cout << is_all_same<int,int,int,int,int&>::value << std::endl ;//false 
    std::cout << is_all_same<int,int,int,int,int>::value << std::endl ;//true
    std::cout << std::endl ;
    std::cout << is_one_same<int,int,float,double,int&>::value << std::endl ;//true
    std::cout << is_one_same<int,std::ostream,float,double,unsigned int>::value << std::endl ;//false
    std::cout << is_one_same<int,int,int,int,int>::value << std::endl ;//true
}
http://rextester.com/CZFY1496

Для чего это мне может пригодится, опишу в теме Обертка над boost::lexical_cast для работы с unsigned типами
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
01.02.2016, 03:16
Ответы с готовыми решениями:

Используя производные классы, определить класс параметризованного списка одного из следующих типов. Применить его для построения списка объектов указа
Используя производные классы, определить класс параметризованного упорядоченного списка. Применить...

Применение типов
Пытаюсь перейти от Prolog к Haskel. Надо сделать вычисление арифметического выражения. Пишу...

Применение RAW типов
Добрый день ! В каких случаях надо применять RAW типы ? За пример буду благодарен !

Применение параметризированных типов
Здравствуйте! Помогите, пожалуйста, разобраться. Не знаю как передать созданный параметризованный...

17
В астрале
Эксперт С++
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
01.02.2016, 10:35 2
Croessmah, В С++14 можно юзать std::logical_and/std::logical_or они constexpr cудя по документации.
Есть подозрение что можно реализовать is_same проще.
1
Неэпический
17870 / 10635 / 2054
Регистрация: 27.09.2012
Сообщений: 26,736
Записей в блоге: 1
01.02.2016, 10:38  [ТС] 3
Цитата Сообщение от ForEveR Посмотреть сообщение
В С++14 можно юзать std::logical_and/std::logical_or они constexpr cудя по документации.
Да, в 14-ом стандарте оно constexpr.
Но на случай, если переделать нужно будет на 11-ый, пусть висит.
0
5231 / 3204 / 362
Регистрация: 12.12.2009
Сообщений: 8,113
Записей в блоге: 2
01.02.2016, 11:12 4
Цитата Сообщение от ForEveR Посмотреть сообщение
Есть подозрение что можно реализовать is_same проще.
Поддерживаю.
Глядя на код, складывается впечатление, что хотелось применить как можно больше всяких фич (так бывает после прочтения новой книги), из-за чего код получился неоправданно сложный.

Не по теме:

После того, как я научился применять SFINAE-фичи из С++11 я написал в рабочем проекте класс, в котором один и тот же метод реализован для разных типов при помощи enable_if, тогда мне показалось это круто. Уже позже глядя на это я понял, что это решается банальной перегрузкой, которая описана в начале любой книги по С++ для начинающих. Не надо доводить себя до такого, это плохо :) Если есть простое простое решение - нужно использовать простое решение.

0
Неэпический
17870 / 10635 / 2054
Регистрация: 27.09.2012
Сообщений: 26,736
Записей в блоге: 1
01.02.2016, 12:35  [ТС] 5
Цитата Сообщение от Kastaneda Посмотреть сообщение
Поддерживаю.
Как раз занимаюсь

Добавлено через 27 минут
Переделал так:
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
// =========================================================================================================
// ================================================is_same_list=============================================
// =========================================================================================================
 
 
#include <type_traits>
 
namespace detail
{
 
    template<
        template<class T> class LogicTemplate,
        typename SameType
    >
 
    constexpr bool
    is_same_list_impl()
    {
        return !LogicTemplate<bool>()(true,false) ;
    }
 
 
    template<
    template<class T> class LogicTemplate,
        typename SameType,
        typename FirstType,
        typename ... Args
    >
    constexpr bool
    is_same_list_impl()
    {
        return
                LogicTemplate<bool>()(std::is_same<SameType, FirstType>::value,
                    is_same_list_impl<LogicTemplate, SameType, Args...>()
                ) ;
    }
 
 
 
}//end of detail
 
 
 
 
namespace compile_time
{
    template<class T>
    struct logical_and : public std::binary_function<T,T,bool>
    {
        constexpr bool operator()(const T& first, const T& second) { return first && second ; }
    };
 
 
    template<class T>
    struct logical_or : public std::binary_function<T,T,bool>
    {
        constexpr bool operator()(const T& first, const T& second) { return first || second ; }
    };
}//end of compile_time
 
 
 
 
template<typename SameType, typename ... Args>
struct is_all_same
{
    static constexpr bool value =
            detail::is_same_list_impl<
                compile_time::logical_and,
                SameType, Args...
            >() ;
};
 
 
template<typename SameType, typename ... Args>
struct is_one_same
{
    static constexpr bool value =
            detail::is_same_list_impl<
                compile_time::logical_or,
                SameType, Args...
            >() ;
};
 
 
 
 
 
// =========================================================================================================
// =========================================================================================================
// =========================================================================================================
Почему-то ночью так не получалось,
видать спал больше

Добавлено через 8 минут
Цитата Сообщение от ForEveR Посмотреть сообщение
В С++14 можно юзать std::logical_and/std::logical_or они constexpr cудя по документации.
Оставил свое, только переделал под один интерфейс.
В gcc 4.9.3 с ключем -std=c++14
всё равно std::logical_and/std::logical_or без constexpr
Печалька.
0
Игогошка!
1801 / 708 / 44
Регистрация: 19.08.2012
Сообщений: 1,367
01.02.2016, 14:09 6
Croessmah, я мельком глянул, наверное что-то упустил, но почему так не катит?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
template <class ...T> struct is_all_same;
 
template <class T>
struct is_all_same<T> {
    static constexpr bool value = true;
};
 
template <class T, class U, class... V>
struct is_all_same<T, U, V...> {
    static constexpr bool value = std::is_same<T, U>() && is_all_same<U, V...>::value;
};
 
template <class ...T> struct is_one_same;
 
template <class T>
struct is_one_same<T> {
    static constexpr bool value = false;
};
 
template <class T, class U, class... V>
struct is_one_same<T, U, V...> {
    static constexpr bool value = std::is_same<T, U>() || is_one_same<T, V...>::value;
};
4
Неэпический
17870 / 10635 / 2054
Регистрация: 27.09.2012
Сообщений: 26,736
Записей в блоге: 1
01.02.2016, 14:23  [ТС] 7
Цитата Сообщение от ct0r Посмотреть сообщение
наверное что-то упустил, но почему так не катит?
Да я ночью что только не перепробовал - не канает.
Но это я что-то упустил, а не Вы.

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

Не по теме:

Цитата Сообщение от Kastaneda Посмотреть сообщение
SFINAE-фичи из С++11 я написал в рабочем проекте класс
я учусь, мне можно :D

0
Неэпический
17870 / 10635 / 2054
Регистрация: 27.09.2012
Сообщений: 26,736
Записей в блоге: 1
01.02.2016, 14:39  [ТС] 8
Цитата Сообщение от Kastaneda Посмотреть сообщение
нужно
В конце же останется
C++
1
is_all_same<U, пусто>::value;
Но, думаю, и так и так сработает.
0
5231 / 3204 / 362
Регистрация: 12.12.2009
Сообщений: 8,113
Записей в блоге: 2
01.02.2016, 14:50 9
Цитата Сообщение от Croessmah Посмотреть сообщение
В конце же останется
не, не осталось бы, просто этот вариант раньше бы вызвался, чем вариант с одним <T>. Но вариант с одним <T> тоже рабочий, я просто прогнал.

Добавлено через 13 секунд
Цитата Сообщение от Croessmah Посмотреть сообщение
и так и так сработает.
ага

Не по теме:

Цитата Сообщение от Croessmah Посмотреть сообщение
я учусь, мне можно
Я тоже учусь, только прямо в рабочем проекте, и поскольку я тут ведущий инженер, мне тоже можно :D

0
Неэпический
17870 / 10635 / 2054
Регистрация: 27.09.2012
Сообщений: 26,736
Записей в блоге: 1
01.02.2016, 15:20  [ТС] 10

Не по теме:

Цитата Сообщение от Kastaneda Посмотреть сообщение
Я тоже учусь, только прямо в рабочем проекте, и поскольку я тут ведущий инженер, мне тоже можно
И меня научи :hysteric:



Добавлено через 9 минут
Во, понял что я упустил.
C++
1
2
3
4
template <class T, class U, class... V>
struct is_all_same {//забыл <T, U, V...>
    static constexpr bool value = std::is_same<T, U>() && is_all_same<U, V...>::value;
};
во всяком случае, список ошибок тот же
0
18840 / 9839 / 2408
Регистрация: 30.01.2014
Сообщений: 17,280
02.02.2016, 13:07 11
Лучший ответ Сообщение было отмечено Новичок как решение

Решение

ct0r, Croessmah, Можно проще и без рекурсии:
C++
1
2
3
4
5
6
7
template <typename ...T>
struct pack {};
 
template <typename T, typename... V>
struct is_all_same
    : std::is_same< pack<T, V...>, pack<V..., T> >
{ };
13
5231 / 3204 / 362
Регистрация: 12.12.2009
Сообщений: 8,113
Записей в блоге: 2
02.02.2016, 13:17 12
DrOffset, не сразу понял, круто!
0
Игогошка!
1801 / 708 / 44
Регистрация: 19.08.2012
Сообщений: 1,367
02.02.2016, 13:30 13
DrOffset, я бы так скорее всего не писал, но прием забавный однако
0
DrOffset
02.02.2016, 13:59
  #14

Не по теме:

Цитата Сообщение от ct0r Посмотреть сообщение
я бы так скорее всего не писал
Почему?

0
ct0r
02.02.2016, 14:13
  #15

Не по теме:

Цитата Сообщение от DrOffset Посмотреть сообщение
Почему?
Потому что при чтении недостаточно просто бросить взгляд на код, чтобы понять, как оно работает и почему. Вон даже Kastaneda сразу не понял :D Ну и хочется одинаковой структуры с is_one_same.

0
5231 / 3204 / 362
Регистрация: 12.12.2009
Сообщений: 8,113
Записей в блоге: 2
02.02.2016, 15:18 16
Блин, не могу идею дожевать, просто рабочее время трачу, пора завязывать, работать надо. Если кто-то доведет до ума, буду признателен. Либо я завтра наверное выделю на это время, доделаю.

C++
1
2
3
4
5
6
template<typename T, typename ... Args>
struct is_same
{
   static constexpr bool check(std::initializer_list<bool> l) { return true; } // это "для фона", смысл в том, что у нас есть готовый список bool'ов
   static constexpr bool value = check({ std::is_same<T, Args>::value ... });
};
0
279 / 39 / 13
Регистрация: 11.10.2015
Сообщений: 405
14.04.2017, 17:41 17
DrOffset, я не очень понимаю для чего тут параметры шаблона меняются наизнанку...мудреный код у вас вышел

Добавлено через 54 секунды
Kastaneda, мне кажется что тут через параметр пэк и рекурсию раскрывать нужно всю эту канитель
0
Любитель чаепитий
3742 / 1798 / 566
Регистрация: 24.08.2014
Сообщений: 6,016
Записей в блоге: 1
14.04.2017, 19:47 18
Цитата Сообщение от zarko97 Посмотреть сообщение
я не очень понимаю для чего тут параметры шаблона меняются наизнанку...
ну смотри, каждый инстанс шаблона создаёт новый тип.
как будет работать:
is_all_same<int, int, int> == std::is_same<pack<int, int, int>, pack<int, int, int>>;
is_all_same<int, int&, int> == std::is_same<pack<int, int&, int>, pack<int&, int, int>>;
как видишь, во втором случае типы не совпадают.
1
14.04.2017, 19:47
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
14.04.2017, 19:47
Помогаю со студенческими работами здесь

Применение обнуляемых типов в C#
Всем добрый вечер! На данный момент изучаю сей прекрасный язык и остановился на главе,...

Применение null-совместимых типов, проверка корня
Задание звучит так: Разработать программу, в которой определена функция вычисления квадратного...

Применение в программах однозвсвязного списка
Написать программу работы с базой данных. База хранится в оперативной памяти в виде структуры....

Ввод данных из списка с применение формулы
ВСем привет. Есть список из трех наименований, требуется при выборе одного из наименования, в...


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

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru