欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 时评 > C++ 20 Concept

C++ 20 Concept

2024/10/24 0:48:59 来源:https://blog.csdn.net/fengqiao1999/article/details/143094588  浏览:    关键词:C++ 20 Concept
    concept主要用来定义模板参数的约束,最明显的作用就是在模板参数不满足类型的约束时编译器不再给出几千行奇奇怪怪的错误。当然还有其它的作用,比如说concepts可以用来实现函数的重载、新的concepts可以基于已有的concepts定义从而进行扩展等等下面以实现通用参数类型转换器来展示concept的使用方法。假设输入类型 IN, 输出类型 OUT,针对不同的场景,来进行不同的实现
  •       1、IN、OUT一致, 可以直接输出
    
  •       2、可以通过std::stringstream来进行输入、输出进行转换的 
    
  •       3、复杂容器类型
    

    1、 判断IN、OUT是否一致

template<typename IN, typename OUT>
concept is_same_type =  std::is_same<IN, OUT>::value;

2、判断是否可以进行范围操作

template <typename BEG, class END>
concept item_range = requires(BEG bg, END ed) {{ ++bg };{ *bg };requires !std::is_void_v<decltype(*bg)>;{ bg != ed };
};template <typename T>
concept iter_able = std::is_array_v<T>|| requires(T value) {{ value.begin() };{ value.end() };requires item_range<decltype(value.begin()), decltype(value.end())>;}|| requires(T value) {{ std::begin(value) };{ std::end(value) };requires item_range<decltype(std::begin(value)), decltype(std::end(value))>;};

3、判断是否可以进程insert操作的容器

template<typename T>
concept is_container = requires(T res, T::value_type v) {res.insert(res.begin(), v);
};

4、判断是否符合pair的容器

template<typename T>
concept is_pair_container = requires(T res, T::value_type v) {res.emplace(v);v.first;v.second;
};

转换器代码

#include <sstream>
#include <string>
#include <iostream>
#include <map>
#include <vector>
#include <list>
#include <concepts>//参数转换类
template<typename OUT>
class Convert
{
public://输入、输出类型一致template<typename IN>requires is_same_type<IN, OUT>Convert(const IN& val):m_value(val){}template<typename IN>requires (!is_same_type<IN, OUT> &&  !(iter_able<IN> &&  iter_able<OUT>))Convert(const IN& val){std::stringstream ss;ss << val;//向流中传值ss >> m_value;//向result中写入值}Convert(const char* val){std::stringstream ss;ss << val;//向流中传值ss >> m_value;//向result中写入值}//容器类转换辅助函数template<typename IN>requires (is_container<OUT> && !is_pair_container<OUT>)void ConvertHelper(const IN& val){m_value.insert(m_value.end(), Convert<typename OUT::value_type>(val)());}template<typename IN>requires (!is_container<OUT>)void ConvertHelper(const IN& val){throw "无效容器";}template<typename IK, typename IV>requires is_pair_container<OUT>void ConvertHelper(const std::pair<IK, IV>& val){m_value.emplace(Convert<typename std::decay<typename OUT::value_type::first_type>::type>(val.first)(), Convert<typename std::decay<typename OUT::value_type::second_type>::type>(val.second)());}template<typename IK, typename IV>requires (!is_pair_container<OUT>)void ConvertHelper(const std::pair<IK, IV>& val){throw "pair 类型只支持同类型容器转换";}//容器转换template<typename IN>	requires (!is_same_type<IN, OUT> && iter_able<IN> && iter_able<OUT> )Convert(const IN& val){for (auto & v : val){ConvertHelper(v);}}OUT operator()(){return m_value;}
public:OUT m_value; 
};//特化
template<>
class Convert<const char*>
{
public://输入、输出类型一致template<typename IN>Convert(const IN& val){std::stringstream ss;ss << val;//向流中传值m_value = ss.str();}const char* operator()(){return m_value.c_str();}
public:std::string m_value; 
};

转换测试


int main(int argc, char* argv[])
{//常用类型转换std::cout <<  Convert<int>(234)() << std::endl;std::cout <<  Convert<int>(std::string("234"))() << std::endl;std::cout <<  Convert<std::string>("456")() << std::endl;std::cout <<  Convert<double>("456.12")() << std::endl;std::cout <<  Convert<const char*>("456.12")() << std::endl;//容器类型转换std::vector<std::string> val = {"123", "345", "345"};auto cValue  = Convert<std::vector<int>>(val)();for(auto item : cValue){std::cout <<  item << std::endl;}//数组向容器转换int a[] = {1,2,3,4,5};auto ca = Convert<std::vector<int>>(a)();for(auto item : ca){std::cout <<  item << std::endl;}//支持pair的容器转换std::map<std::string, std::string> mval  = {{"123", "1"}, {"234", "3"}};auto cmval = Convert<std::map<int, int>>(mval)();for(auto item : cmval){std::cout <<  item.first << ":" << item.second << std::endl;}return 0;
}

总结: 实际应用中,各种类型的转换可能复杂的多,但通过实现不难发现,通过concept来定义模板参数的约束, 可以大大简化模板参数类型的萃取工作。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com