C++ проверка типа данных в шаблоне: ссылка, указатель или объект?
Я могу узнать, к какому типу данных принадлежит параметр шаблона:
template<class... _Ty_node>
Value_polihedral(_Ty_node&&... _nodes) {
if constexpr((_STD is_same<_Ty_node, decltype(_V_nodes)::value_type&>::value && ...)) {
(_V_nodes.emplace_back(_STD forward<_Ty_node>(_nodes)), ...);
} else if constexpr(((_STD is_same<_Ty_node, Point&>::value ||
_STD is_same<_Ty_node, Point3d&>::value) && ...)) {
(_V_nodes.emplace_back(_STD make_shared<Value::Point>(_nodes)), ...);
} else {
static_assert(false, "The function expected a type that matches nodes type. ");
}
_V_nodes_transform.reserve(4);
}
Но как быть, если я не знаю, какой тип может быть на входе и всё, что мне нужно это правильно обработать элементы. Если параметр - указатель, то нужно обращаться через (->), а если ссылка, то через точку(.)
Нужно что-то вроде такого
template<class... _Ty_node>
Value_polihedral(_Ty_node&&... _nodes) {
if constexpr((is_ptr<_Ty_node> && ...)) {
(sum += _nodes->weight, ...); // ->
} else{
(sum += _nodes.weight, ...); // .
}
}
Ответы (1 шт):
Начиная с С++11, в стандартной библиотеке (в файле type_traits) появился шаблон класса is_pointer
template< class T >
struct is_pointer;
Он позволяет проверить, является ли T указателем на обьект или функцию (но не указателем на член класса). Чтобы узнать результат, необходимо обратиться к статическому члену value, который равен true, если T является указателем и false в противном случае.
Пример кода:
#include <iostream>
#include <type_traits>
int main()
{
std::cout << std::is_pointer<int>::value << std::endl; // 0
std::cout << std::is_pointer<int*>::value << std::endl; // 1
return 0;
}
В С++17 появился вспомогательный шаблон переменной
template< class T >
constexpr bool is_pointer_v = is_pointer<T>::value;
который позволяет избежать обращения к члену value.
Пример кода:
#include <iostream>
#include <type_traits>
int main()
{
std::cout << std::is_pointer_v<int> << std::endl; // 0
std::cout << std::is_pointer_v<int*> << std::endl; // 1
return 0;
}
Более подробно здесь: https://en.cppreference.com/w/cpp/types/is_pointer