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

C++

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 1, средняя оценка - 5.00
Croessmah
Ушел
13764 / 8014 / 923
Регистрация: 27.09.2012
Сообщений: 19,725
Записей в блоге: 3
Завершенные тесты: 1
#1

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

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

Итак, 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)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
01.02.2016, 03:16
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Применение is_same для списка типов (C++):

Применение регулярных выражений для парсинга email-ов получателей из emf-файла - C++ Builder
Подскажите как применять регулярные выражения к нескольким строкам (заранее количество не известно) Например есть текст: Если...

Существуют ли MFC'шные функции для преобразования типов? - Visual C++
А существуют MFC'шные ф-ии для преобразования типов?

Определение и использование функций для обработки стандартных типов данных - Visual C++
Заданы три числа. Отрицательные числа заменить абсолютными значениям, нулевые значения – единицами, положительные – увеличить в два раза.

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

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

Найти предельные значения для целочисленных типов. Не использовать заранее определенные константы границ типов. - C++
Буду благодарен! Найти предельные значения для целочисленных типов. Не использовать заранее определенные константы границ типов.

17
ForEveR
В астрале
Эксперт С++
7992 / 4751 / 321
Регистрация: 24.06.2010
Сообщений: 10,547
Завершенные тесты: 3
01.02.2016, 10:35 #2
Croessmah, В С++14 можно юзать std::logical_and/std::logical_or они constexpr cудя по документации.
Есть подозрение что можно реализовать is_same проще.
1
Croessmah
Ушел
13764 / 8014 / 923
Регистрация: 27.09.2012
Сообщений: 19,725
Записей в блоге: 3
Завершенные тесты: 1
01.02.2016, 10:38  [ТС] #3
Цитата Сообщение от ForEveR Посмотреть сообщение
В С++14 можно юзать std::logical_and/std::logical_or они constexpr cудя по документации.
Да, в 14-ом стандарте оно constexpr.
Но на случай, если переделать нужно будет на 11-ый, пусть висит.
0
Kastaneda
Jesus loves me
Эксперт С++
4749 / 2953 / 242
Регистрация: 12.12.2009
Сообщений: 7,491
Записей в блоге: 2
Завершенные тесты: 1
01.02.2016, 11:12 #4
Цитата Сообщение от ForEveR Посмотреть сообщение
Есть подозрение что можно реализовать is_same проще.
Поддерживаю.
Глядя на код, складывается впечатление, что хотелось применить как можно больше всяких фич (так бывает после прочтения новой книги), из-за чего код получился неоправданно сложный.

Не по теме:

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

0
Croessmah
Ушел
13764 / 8014 / 923
Регистрация: 27.09.2012
Сообщений: 19,725
Записей в блоге: 3
Завершенные тесты: 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
ct0r
Игогошка!
1784 / 686 / 42
Регистрация: 19.08.2012
Сообщений: 1,321
Завершенные тесты: 1
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
Croessmah
Ушел
13764 / 8014 / 923
Регистрация: 27.09.2012
Сообщений: 19,725
Записей в блоге: 3
Завершенные тесты: 1
01.02.2016, 14:23  [ТС] #7
Цитата Сообщение от ct0r Посмотреть сообщение
наверное что-то упустил, но почему так не катит?
Да я ночью что только не перепробовал - не канает.
Но это я что-то упустил, а не Вы.

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

Не по теме:

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

0
Croessmah
Ушел
13764 / 8014 / 923
Регистрация: 27.09.2012
Сообщений: 19,725
Записей в блоге: 3
Завершенные тесты: 1
01.02.2016, 14:39  [ТС] #8
Цитата Сообщение от Kastaneda Посмотреть сообщение
нужно
В конце же останется
C++
1
is_all_same<U, пусто>::value;
Но, думаю, и так и так сработает.
0
Kastaneda
Jesus loves me
Эксперт С++
4749 / 2953 / 242
Регистрация: 12.12.2009
Сообщений: 7,491
Записей в блоге: 2
Завершенные тесты: 1
01.02.2016, 14:50 #9
Цитата Сообщение от Croessmah Посмотреть сообщение
В конце же останется
не, не осталось бы, просто этот вариант раньше бы вызвался, чем вариант с одним <T>. Но вариант с одним <T> тоже рабочий, я просто прогнал.

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

Не по теме:

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

0
Croessmah
Ушел
13764 / 8014 / 923
Регистрация: 27.09.2012
Сообщений: 19,725
Записей в блоге: 3
Завершенные тесты: 1
01.02.2016, 15:20  [ТС] #10

Не по теме:

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



Добавлено через 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
DrOffset
7517 / 4513 / 1024
Регистрация: 30.01.2014
Сообщений: 7,362
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
Kastaneda
Jesus loves me
Эксперт С++
4749 / 2953 / 242
Регистрация: 12.12.2009
Сообщений: 7,491
Записей в блоге: 2
Завершенные тесты: 1
02.02.2016, 13:17 #12
DrOffset, не сразу понял, круто!
0
ct0r
Игогошка!
1784 / 686 / 42
Регистрация: 19.08.2012
Сообщений: 1,321
Завершенные тесты: 1
02.02.2016, 13:30 #13
DrOffset, я бы так скорее всего не писал, но прием забавный однако
0
DrOffset
02.02.2016, 13:59
  #14

Не по теме:

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

0
ct0r
02.02.2016, 14:13     Применение is_same для списка типов
  #15

Не по теме:

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

0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
02.02.2016, 14:13
Привет! Вот еще темы с ответами:

Применение strtok() для получения слова - C++
Ребят, задача собственно, такая: у заданного текста поменять местами первое и последнее слово. Алгоритм у меня такой. Я с помощью strtok...

Проблемы с приведением типов для компоранда для qsort - C++
Вот так всё ок (во всяком случаи компилятор не выдвинул никаких предупреждений): int comp(const void* i, const void* j) { Worker*...

Применение Map для парсинга строк с числами - C++
Всем привет. Подскажите пожалуйста, вот например от куда то поступает данные с набором строк где могут быть числа а так же символы....

Применение симплекс-метода для решения задач - C++
Напишите программку для решения этой задачи ,можно решить её также желательно решить её математически)


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

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

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