Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
454 views
in Technique[技术] by (71.8m points)

c++ - Idiomatic way to write concept that says that type is a std::vector

I have the following code that implements following type traits:

  • that type is std::vector
  • that type is std::vector of ints

It 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);
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You can already have shorter code by reusing std::true_type/std::false_type:

template <class T>
struct is_vector : std::false_type {};

template <class T, class A>
struct is_vector<std::vector<T, A>> : std::true_type {};

template <class T>
struct is_vector_of_int : std::false_type {};

template <class A>
struct is_vector_of_int<std::vector<int, A>> : std::true_type {};

Not sure you can have shorter.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...