Способ вывести, если тип из шаблонного класса - PullRequest
0 голосов
/ 28 марта 2019

Я пытался ответить на вопрос в названии, но я в тупике. В основном, пытаясь понять, есть ли встроенный способ сообщить «источник» создания экземпляра шаблона, по крайней мере, для классов. Вот пример того, что я хотел бы сделать:

template<class T>
class A { };

auto a = A<int>();

template<class T>
auto someFunction(T item) {
    if(/* if type of a is from the templated class A */) {
        // yep A<int> is 'from' A.
    }
}

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

Ответы [ 3 ]

4 голосов
/ 28 марта 2019

Может быть с чертами нестандартного типа.

Что-то вроде следующего

template <typename>
struct is_A : public std::false_type
 { };

template <typename T>
struct is_A<A<T>> : public std::true_type
 { };

// ...

template <typename T>
auto someFunction(T item) {
   if( is_A<T>::value ) {
    // yep A<int> is 'from' A.
   }
}

Или, может быть, вы хотите перехватывать не только A<T>, но, в общем, все типы, которые являются шаблономтипа, может быть с неопределенным числом аргументов шаблона?

В этом случае вы можете попробовать что-то вроде следующего

template <typename>
struct is_template : public std::false_type
 { };

template <template <typename...> class C, typename ... Ts>
struct is_template<C<Ts...>> : public std::true_type
 { };

Проблема: эта черта типа перехватывает все типы шаблона с аргументами шаблона типа и только аргументы шаблона.Но не перехватывает, например, std::integer_sequence<int, 0, 1, 2, 3, 4, 5>, который получает тип и некоторый параметр шаблона нетипичного типа.

Вы можете добавить другие специализации для is_template, чтобы перехватывать другие случаи, но вы не можетеопределить специализацию, которая будет охватывать все типы шаблонов (все комбинации параметров шаблона).

1 голос
/ 28 марта 2019

Другой способ, позволяющий производному классу соответствовать:

template <typename T>
std::true_type is_an_A_impl(A<T>*);

std::false_type is_an_A_impl(...);

template <typename T>
using is_a_A = decltype(is_an_A_impl(std::declval<T*>()));
1 голос
/ 28 марта 2019

Использовать черту типа

#include <type_traits>
#include <iostream>

template<class T>
class A { };

auto a = A<int>();

template <typename X>
struct is_from_A : std::false_type {};

template <typename T>
struct is_from_A<A<T>> : std::true_type {};

int main() {
    std::cout << is_from_A<int>::value << "\n";     // 0
    std::cout << is_from_A<A<int>>::value << "\n";  // 1
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...