Reputation: 13
I am new to making my own type traits and I want to make a type trait that allows me to identify if the passed type is the expected container.
template<typename T, typename ... Types>
struct is_array
{
static constexpr bool value = false;
};
template<typename ... Types>
struct is_array<std::array<Types...>>
{
static constexpr bool value = true;
};
I've adopted the format above and it works for all container types except for array:
constexpr bool state = is_array<std::array<int, 5>>::value;
The above evaluates to false when it should be true. This only happens for the array class and I believe it is due to it having 2 template parameters that do not have default values. I am unable to figure out a fix for this.
Upvotes: 0
Views: 103
Reputation: 3849
First, your trait should have one, and only one template parameter: the expected array type:
template<typename T/*, typename ... Types*/>
struct is_array {
static constexpr bool value = false;
};
Second, std::array is defined as:
template<
class T,
std::size_t N
> struct array;
as first type parameter T
and a non-type parameter N
of type std::size_t
.
Therefore, your true specialization should be:
template<typename T, std::size_t N>
struct is_array<std::array<T,N>>
{
static constexpr bool value = true;
};
Note, that instead of defining a member value
, we prefer to inherit from std::true_type and std::false_type which provide some other member alias + conversion operator. The code then becomes:
template<typename T>
struct is_array : std::false_type {};
template<typename T, std::size_t N>
struct is_array<std::array<T,N>> : std::true_type {};
Upvotes: 3