7 / 6 / 3
Регистрация: 30.03.2020
Сообщений: 123
1

Как узнать тип шаблона ф-ии/класса ?

27.04.2020, 15:13. Показов 3264. Ответов 16
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
есть вот такая ф-ия
C++
1
2
3
4
5
6
7
    namespace priv {
#       ifdef _GLIBCXX_VECTOR
        template <class std_vector> bool _FOR_VECTOR_TYPE_CHECK_(const std_vector &vector) {
 
        }
#       endif
    }
Она должна принимать на вход любой параметр, и при условии что тип параметра - std::vector(обратите внимание, неизвестно какого типа сам вектор), она должна возвращать обрабатывать внутри себя там кое-что. У меня пока так получилось
C++
1
 if(!std::is_same <std_vector, std_vector[0]>()) return false;
, но это сработает только при условии наличия перегруженного оператора индексации у класса(

Добавлено через 7 минут
точнее, я там не правильно написал , вот такая проверка:
C++
1
 if(!std::is_same <std_vector,std::vector <decltype(std_vector[0])>>()) return false;
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
27.04.2020, 15:13
Ответы с готовыми решениями:

Как узнать тип данных шаблона функции?
Я старался делать так: #include&lt;iostream&gt; #include&lt;fstream&gt; #include&lt;conio.h&gt; #include&lt;stdlib.h&gt;...

Как ограничить тип данных шаблона класса?
Решил создать два класса: умный массив и его менеджер. Так как массив может хранить любые типы, то...

Параметр шаблона класса как собственный тип данных
Приветствую. Такой вопрос: как перегрузить операторы класса-шаблона, где в качестве аргумента...

Как узнать какой тип у шаблонного класса?
Есть класс с шаблонным массивом: template&lt;class T&gt; class cl1 { private: T mas; И метод,...

16
Комп_Оратор)
Эксперт по математике/физике
8949 / 4703 / 629
Регистрация: 04.12.2011
Сообщений: 13,999
Записей в блоге: 16
27.04.2020, 15:25 2
Цитата Сообщение от Tapacuk Посмотреть сообщение
есть вот такая ф-ия
У кого и зачем? Можно работать с итераторами. Но если вы работаете со ссылкой на вектор, то можете параметром сделать именно тип элемента. А на уровне контейнера можно так обобщить, если подойдёт:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <vector>
#include <list>
using namespace std;
template<class Container>
void foo(const Container &container)
{
    for(const auto &elem: container) cout<<elem<<' ';    
}
int main()
{
vector<int>v{1,2,3,4,5};
foo(v);
cout<<endl;
list<char>l{'a','b','c'};
foo(l);
return 0;
}
0
7 / 6 / 3
Регистрация: 30.03.2020
Сообщений: 123
27.04.2020, 15:31  [ТС] 3
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <vector>
#include <list>
 
template<class Container>
void foo(const Container &container) { 
    for(const auto &elem: container) std::cout << elem << ' ';  
}
 
int main() {
    vector <int> v{ 1, 2, 3, 4, 5 };
    foo(v);
    std::cout << '\n';
    list <char> l { 'a', 'b', 'c' };
    foo(l);
    foo(12); // А если кто-нибудь так сделает?
}
Вся проблема как раз и заключается в том, чтобы обрабатывать некорректный контейнер.
0
Комп_Оратор)
Эксперт по математике/физике
8949 / 4703 / 629
Регистрация: 04.12.2011
Сообщений: 13,999
Записей в блоге: 16
27.04.2020, 15:35 4
Цитата Сообщение от Tapacuk Посмотреть сообщение
Вся проблема как раз и заключается в том, чтобы обрабатывать некорректный контейнер.
Объясните толком.
0
Эксперт С++
8739 / 4317 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
27.04.2020, 15:37 5
Лучший ответ Сообщение было отмечено Tapacuk как решение

Решение

Цитата Сообщение от Tapacuk Посмотреть сообщение
ifdef _GLIBCXX_VECTOR
нафига ты захламляешь исходник этимими несущественными деталями?

Цитата Сообщение от Tapacuk Посмотреть сообщение
тип параметра - std::vector
std::vector - это шаблон типа, а не сам тип.

Цитата Сообщение от Tapacuk Посмотреть сообщение
_FOR_VECTOR_TYPE_CHECK_
идентификаторы которые начинаются с _ и заглавной буквы - зарезервированы для нужд языка,
и не должны быть использованы ни в каких иных случаях.

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


https://rextester.com/VCL29389

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <vector>
 
template <class... Types> 
void example(const std::vector<Types...>& vec) 
{
    std::cout << "vector:\n";
    for(const auto& el: vec)
        std::cout << el << ", ";
    std::cout << '\n';
}
 
int main()
{
    std::vector<int> vec { 1, 2, 3 };
    
    example(vec);
}
Добавлено через 1 минуту
Цитата Сообщение от Tapacuk Посмотреть сообщение
foo(12); // А если кто-нибудь так сделает?
тогда оно просто не скомпилируется.

Цитата Сообщение от Tapacuk Посмотреть сообщение
обрабатывать некорректный контейнер.
каким образом?
1
7 / 6 / 3
Регистрация: 30.03.2020
Сообщений: 123
27.04.2020, 15:42  [ТС] 6
C++
1
2
3
template <class std_vector> bool isVector(const std_vector &vector) {
    if( /* Проверка на то, что это std::vector */ ) return true;
    return false;
Нужно как-то создать такую ф-ию.

Добавлено через 4 минуты
А ну да я затупил сори :/
0
Эксперт С++
8739 / 4317 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
27.04.2020, 15:43 7
Цитата Сообщение от Tapacuk Посмотреть сообщение
Нужно как-то создать такую ф-ию.
https://rextester.com/QFDE29422

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
#include <iostream>
#include <vector>
 
template <class t> struct is_vector
{
    enum { value = false };
};
template <class... types> struct is_vector< std::vector<types...> >
{
    enum { value = true };
};
 
 
template <class t> 
constexpr bool is_vector_v = is_vector<t>::value;
 
int main()
{
    using vec = std::vector<int>;
    
    constexpr bool failed = !is_vector_v<int>;
    constexpr bool success= is_vector_v<vec>;    
    
    if(failed)
        std::cout << "'int' is not vector\n"; 
    
    if(success)
        std::cout << "'vec' is vector\n"; 
}
1
7 / 6 / 3
Регистрация: 30.03.2020
Сообщений: 123
27.04.2020, 15:54  [ТС] 8
Хотя нет. Не всё. Короче у меня есть функция вида
C++
1
template <class T> bool func() {}
И вот в ней мне нужно как-то в
C++
1
T
распознать вектор, а у вектора - тип, причём если передан не вектор, то она не должна крашиться, а возвращать
C++
1
false
Добавлено через 31 секунду
Понял, принял, опознал...

Добавлено через 4 минуты
О, кстати, hoggy, это ты).
Я когда задавал вопрос думал: hoggy ответит или не hoggy?
...

Добавлено через 39 секунд
Ты вездесущ в этом разделе)
Я когда сюда заходил ответы поискать почти везде был ты
0
Комп_Оратор)
Эксперт по математике/физике
8949 / 4703 / 629
Регистрация: 04.12.2011
Сообщений: 13,999
Записей в блоге: 16
27.04.2020, 16:13 9
Вопрос не понятен. Ответ тоже не слишком, но лучше пока не знаю:
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
#include <iostream>
#include <vector>
#include <list>
#include <typeinfo>
using namespace std;
template<class Container>
void foo(const Container &container)
{
    for(const auto &elem: container) cout<<elem<<' ';
}
 
template<class T>
void foo(const vector<T> &container)
{
    cout<<"vector<"<<typeid(T).name()<<">\n";
    for(const auto &elem: container) cout<<elem<<' ';
 
}
 
int main()
{
    vector<int>vi{1,2,3,4,5};
    foo(vi);
    cout<<endl;
    vector<float>vf{1,2,3,4,5};
    foo(vf);
    cout<<endl;
    list<char>l{'a','b','c'};
    foo(l);
    return 0;
}
0
6091 / 3449 / 1402
Регистрация: 07.02.2019
Сообщений: 8,768
27.04.2020, 18:42 10
Цитата Сообщение от IGPIGP Посмотреть сообщение
Ответ тоже не слишком, но лучше пока не знаю
Если обобщить, то можно как-нибудь так:
Кликните здесь для просмотра всего текста
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
#include <type_traits>
 
namespace traits
{
    // лёгкая обёртка для типа
    template<class T> struct type_holder {};
    // лёгкая обёртка для шаблона, без необходимости параметризовать его
    template<template<class...> class T> struct template_holder {};
    // список идентификаторов шаблонов (понадобится для поиска среди нескольких шаблонов)
    template<template<class...> class... Ts> struct template_list {};
    // вытаскиваем идентификатор шаблона из типа
    template<template<class...> class T, class... Ts>
    constexpr template_holder<T> wrap_template(type_holder<T<Ts...>>) { return {}; }
    // перегрузка, если тип не является параметризованным шаблоном
    template<class T>
    constexpr type_holder<T> wrap_template(type_holder<T>) { return {}; }
    // проверка, является ли тип T параметризованным шаблоном с идентификатором U
    template<class T, template<class...> class U>
    constexpr bool is_same_id(type_holder<T> t = {}, template_holder<U> tmp = {})
    {
        return ::std::is_same<decltype(traits::wrap_template(t)), decltype(tmp)>::value;
    }
    // поиск соответствия идентификатора шаблона типа T(если это инстанцированный шаблон) среди идентификаторов шаблонов Ts
    template<class T, template<class...> class... Ts>
    constexpr bool any_of_id(type_holder<T> t = {}, template_list<Ts...> = {})
    {
        return (... || is_same_id(t, template_holder<Ts>{}));
    }
}
 
#include <iostream>
#include <vector>
#include <set>
#include <list>
 
// перегрузка оператора вывода в поток для векторов, сетов, листов (нужное добавить/убрать по желанию)
template<class Container, std::enable_if_t<traits::any_of_id<Container, ::std::set, ::std::vector, ::std::list>(), int> = 0>
::std::ostream& operator<<(::std::ostream& os, const Container& c)
{
    for (auto&& val : c)
        os << val << ", ";
    return os;
}
 
int main()
{
    ::std::vector<int> vec{ 1, 2, 3, 4, 5 };
    ::std::set<double> set{ 1.5, 2.5, 3.5, 4.5, 5.5 };
    ::std::list<char> lst{ 'a', 'b', 'c', 'd', 'e' };
 
    std::cout
        << vec << std::endl
        << set << std::endl
        << lst << std::endl;
 
    static_assert(traits::is_same_id<decltype(vec), ::std::vector>());
    static_assert(traits::is_same_id<std::set<float>, ::std::set>());
    //static_assert(traits::is_same_id<double, ::std::list>());
}

https://rextester.com/HYGIF92774
1
Комп_Оратор)
Эксперт по математике/физике
8949 / 4703 / 629
Регистрация: 04.12.2011
Сообщений: 13,999
Записей в блоге: 16
27.04.2020, 19:52 11
zayats80888, в строке: 27
,,,\main.cpp||In function 'constexpr bool traits::any_of_id(traits::type_holder<T>, traits::template_list<Ts ...>)':|
F:\CodeBlocksPrjsCpp\ConsoleCpp\ConsoleCppTest\main.cpp|8651|error: expected primary-expression before '...' token|
и таких сообщений не счесть.
Но не суть, у меня MinGW не самый свежий, хотя 11 заявлен. По духу вашего кода определение типа делается по известному наперёд набору типов. Так или иначе, а это мне ещё понятно. Я написал бы иначе, но возможно не лучше.
А в вопросе:
Цитата Сообщение от Tapacuk Посмотреть сообщение
и при условии что тип параметра - std::vector(обратите внимание, неизвестно какого типа сам вектор),
Это конечно смесь из букв, но я тут увидел желание получить буквально любой тип. Даже какой-то пользовательский ZdravstvuyVasyaYaSneslasya.
Я уж не говорю, что там может быть вектор множеств туплов векторов множеств на типе ЗдравствуйВася...
Вот я и написал через typeinfo. Непереносимо, но что-то квакнет.
В этом всём есть один смешной вопрос. Когда в стандарт языка, где тип, - центральная концепция будут введены строковые сигнатуры (имена) типов, хотя бы для встроенных... О правилах генерации сложных имён включая пользовательские я уже и не говорю?
0
6091 / 3449 / 1402
Регистрация: 07.02.2019
Сообщений: 8,768
27.04.2020, 20:01 12
Цитата Сообщение от IGPIGP Посмотреть сообщение
и таких сообщений не счесть
это fold expression (since c++17), можно заменить на
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
template<class T, template<class...> class... Ts>
    constexpr bool any_of_id(type_holder<T> t = {}, template_list<Ts...> = {})
    {
        bool result[]{ false, is_same_id(t, template_holder<Ts>{})... };
        for (auto res : result)
        {
            if (res) return true;
        }
        return false;
    }


Добавлено через 2 минуты
ну и строка нужна в static_assert
static_assert(... , "some message")
0
Комп_Оратор)
Эксперт по математике/физике
8949 / 4703 / 629
Регистрация: 04.12.2011
Сообщений: 13,999
Записей в блоге: 16
27.04.2020, 20:02 13
...\main.cpp|8666|error: 'std::enable_if_t' has not been declared|
не суть - количество ошибок необозримо. Если сделаете для 11 - маякните, - посмотрю)
0
zayats80888
27.04.2020, 20:11
  #14

Не по теме:

Цитата Сообщение от IGPIGP Посмотреть сообщение
Если сделаете для 11 - маякните, - посмотрю)
Писать рекурсивные метафункции реально не охота :) Всё таки 20 год на дворе

0
Комп_Оратор)
Эксперт по математике/физике
8949 / 4703 / 629
Регистрация: 04.12.2011
Сообщений: 13,999
Записей в блоге: 16
27.04.2020, 20:19 15
Цитата Сообщение от zayats80888 Посмотреть сообщение
Писать рекурсивные метафункции реально не охота Всё таки 20 год на дворе
Я недавно спросил одного архитектора, о том, почему бы не перевести проект на C++17 и получил ответ что при его жизни он вряд ли будет переведен на С++14. Так что о 20-м и речи нет) Это в продакшене. Я не говорю, что это везде так. Наверняка нет. Но всё же в данном разделе, это перебор) Но как бы там ни было вопрос не сформулирован.
Ваш код сможет описать тип параметра вектора в таком разе:
C++
1
vecctor<vector<SomeClass>> v ;
если SomeClass это клиентский тип о котором ваш код ни чего не знает?
0
6091 / 3449 / 1402
Регистрация: 07.02.2019
Сообщений: 8,768
27.04.2020, 20:28 16
Цитата Сообщение от IGPIGP Посмотреть сообщение
Ваш код сможет описать тип параметра вектора в таком разе
Всмысле описать? Скажите что нужно проверить (какое статическое утверждение)?
0
Комп_Оратор)
Эксперт по математике/физике
8949 / 4703 / 629
Регистрация: 04.12.2011
Сообщений: 13,999
Записей в блоге: 16
27.04.2020, 20:48 17
Цитата Сообщение от zayats80888 Посмотреть сообщение
Скажите что нужно проверить (какое статическое утверждение)?
Если бы знать. Я же говорю:
Цитата Сообщение от IGPIGP Посмотреть сообщение
вопрос не сформулирован
Цитата Сообщение от Tapacuk Посмотреть сообщение
Как узнать тип шаблона ф-ии
Каждый Охотник Желает Знать Где Сидит Фиолетовый тип инстанса (у шаблона нет типов, там абстрактное имя для конкретизации).
0
27.04.2020, 20:48
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
27.04.2020, 20:48
Помогаю со студенческими работами здесь

Как узнать тип производного класса в функции базового
Всем привет! Есть иерархия классов: class1 -&gt; class2-&gt;class3 class2-&gt;class4 ...

Как узнать тип шаблонного класса во время выполнения программы?
Тоесть: имеем класс list&lt;int&gt; или list&lt;double&gt;, и как узнать какой это тип? Ну int или double?

Как в конструкторе атрибута узнать тип класса, которому этот атрибут принадлежит?
Есть куча видовых моделей и куча окон. Также есть синглтон - диспетчер сопоставления видов и...

Узнать тип класса и создать такой же
Сабж. public static IList&lt;T&gt; FindAll&lt;T&gt;(IList&lt;T&gt; list, CheckDelegate&lt;T&gt; check,...

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

Void как подстановочный тип шаблона
Есть шаблон функции такого типа: template &lt;typename myClass, typename in_t, typename out_t,...


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

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

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