惯用的方式写概念,说该类型是std :: vector [英] Idiomatic way to write concept that says that type is a std::vector

查看:43
本文介绍了惯用的方式写概念,说该类型是std :: vector的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下代码实现以下类型特征:

I have the following code that implements following type traits:

  • 类型为 std :: vector
  • 类型为整数的 std :: vector

它可以工作,但是很冗长.
有没有使用概念写这个的更短/更巧妙的方法?
我知道我可以从range-v3或其他类似的库中窃取概念,但是让我们假设我想自己实现它.

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);
}

推荐答案

代码高尔夫!这更短:

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>;

具有预期的行为( https://wandbox.org/permlink/iZpUZRC5s73co0bV ),并且 is_specialization 特性可以在仅接受类型参数的任何类模板中重复使用.

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.

这篇关于惯用的方式写概念,说该类型是std :: vector的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆