In the following code, I am using a template function and type traits to distinguish between an integer type (else case) and array type. I would expect the output to be int
and array
respectively, instead I get int
int
with the two calls that instantiates the template functions respectively with an int type and an array type:
Why is that?
#include <iostream>
#include <array>
template <typename T>
inline static void constexpr SetCoordinates()
{
if (std::is_array<T>::value)
std::cout<<"array\n";
else
std::cout<<"int\n";
}
int main()
{
int a = 6;
std::array<int, 4> arr = {1,2,3,4};
SetCoordinates<decltype(a)>();
SetCoordinates<decltype(arr)>();
return 0;
}
CodePudding user response:
The std::is_array
does not include the case of std::array
; Rather, it only checks if the type is just a normal array type(i.e T[]
, T[N]
). Hence, your if
statement lands in the false branch.
You have to provide a custom traits for the std::array
for this to happen:
#include <type_traits> // std::true_type, std::false_type, std::is_array
template <typename T> struct is_std_array : std::false_type{};
template < typename T, std::size_t N>
struct is_std_array<std::array<T, N> > : std::true_type { };
template <typename T>
inline static void constexpr SetCoordinates()
{
if (std::is_array<T>::value || is_std_array<T>::value)
// ^^^^^^^^^^^^^^^^^^^^^^^^^-->and check
std::cout << "array\n";
else
std::cout << "int\n";
}
CodePudding user response:
In this simple case I can use std::is_integral
, providing the template function is called only with those two types:
#include <iostream>
#include <array>
template <typename T>
inline static void constexpr SetCoordinates()
{
if (std::is_integral<T>::value)
std::cout<<"int\n";
else
std::cout<<"array\n";
}
int main()
{
int a = 6;
std::array<int, 4> arr = {1,2,3,4};
SetCoordinates<decltype(a)>();
SetCoordinates<decltype(arr)>();
return 0;
}