I have the following code that implements following type traits:
std::vector
std::vector
of intsIt works but it is quite verbose.
Is there a shorter/nicer way to write this using concepts?
I know I can steal concepts from range-v3 or some other similar library, but let's assume I want to implement it myself.
#include <iostream>
#include <string>
#include <type_traits>
#include <vector>
template <class T>
struct is_vector {
static constexpr bool value = false;
};
template <class T, class A>
struct is_vector<std::vector<T, A> > {
static constexpr bool value = true;
};
template <class T>
struct is_vector_of_int {
static constexpr bool value = false;
};
template <class A>
struct is_vector_of_int<std::vector<int, A> > {
static constexpr bool value = true;
};
// TODO add _v bool
template<typename T>
concept bool Vec = is_vector<T>::value;
template<typename T>
concept bool VecInt = is_vector_of_int<T>::value;
struct my_allocator : public std::allocator<int>{
};
template<VecInt V>
size_t func (const V& v){
return v.size();
}
int main()
{
static_assert(!is_vector<std::string>::value);
static_assert(is_vector<std::vector<int, my_allocator>>::value);
static_assert(is_vector<std::vector<int, std::allocator<int>>>::value);
static_assert(!is_vector_of_int<std::string>::value);
static_assert(is_vector_of_int<std::vector<int, my_allocator>>::value);
static_assert(!is_vector_of_int<std::vector<float, my_allocator>>::value);
static_assert(Vec<std::vector<float, my_allocator>>);
static_assert(!VecInt<std::vector<float, my_allocator>>);
static_assert(Vec<std::vector<int>>);
std::vector<float> vf{1.1,2.2,3.3};
std::vector<int> vi{1,2,3};
// std::cout << func (vf);
std::cout << func (vi);
}
Code golf! This is shorter:
template<class, template<class...> class>
inline constexpr bool is_specialization = false;
template<template<class...> class T, class... Args>
inline constexpr bool is_specialization<T<Args...>, T> = true;
template<class T>
concept bool Vec = is_specialization<T, std::vector>;
template<class T>
concept bool VecInt = Vec<T> &&
std::is_same_v<int, typename T::value_type>;
Has the intended behavior (https://wandbox.org/permlink/iZpUZRC5s73co0bV), and the is_specialization
trait is reusable with any class template that accepts only type parameters.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With