C++20模板类Objects_handlers概念的模板参数填充及使用问题
解决方案
1. 先构造测试用的合法Traits类型
你需要一个明确满足Traits概念的桩类型,用来实例化待校验的模板模板参数,避免概念校验时无合法参数可用:
namespace concepts::detail { // 内部测试桩类型,完全符合Traits要求 struct DummyValidTraits { static constexpr std::string_view token = "dummy_test"; }; static_assert(Traits<DummyValidTraits>); }
2. 修正Objects_handlers概念定义
直接用上面的测试桩类型作为模板参数填入即可,只要待校验的模板用任意合法Traits(这里用测试桩代表所有合法Traits)实例化后,能对应处理指定对象类型,就符合要求:
template<template <concepts::Traits> class ObjectsHandlersT, typename ObjectT> concept Objects_handlers = requires(const ObjectT& obj) { { ObjectsHandlersT<concepts::detail::DummyValidTraits>::handle_object(obj) } -> std::same_as<std::string>; };
注意:标准库保留所有下划线开头、首字母大写的标识符,你的
_Traits、_Objects_handlers这类命名属于未定义行为,建议改为TraitsT、ObjectsHandlersT这类符合规范的命名。
3. 适配database类的概念约束
你原来的用法错误是因为Objects_handlers是二元概念,需要同时传入「处理器模板」和「待处理对象类型」两个参数才能使用。如果要校验处理器支持所有object_one/object_two/object_three类型,可以封装一个一元的综合校验概念:
// 先定义你需要支持的所有对象类型列表 using SupportedObjects = std::tuple<object_one, object_two, object_three>; // 辅助实现:校验处理器对列表里所有对象都满足要求 template<template <concepts::Traits> class ObjectsHandlersT, typename ObjectTuple> struct all_supported_handlable_impl; template<template <concepts::Traits> class ObjectsHandlersT, typename... Objs> struct all_supported_handlable_impl<ObjectsHandlersT, std::tuple<Objs...>> { static constexpr bool value = (Objects_handlers<ObjectsHandlersT, Objs> && ...); }; // 最终可用的一元概念:处理器支持所有指定类型 template<template <concepts::Traits> class ObjectsHandlersT> concept AllObjectsHandlers = all_supported_handlable_impl<ObjectsHandlersT, SupportedObjects>::value;
之后database类就可以直接用这个一元概念做约束:
template<concepts::AllObjectsHandlers HandlerT> class database { // 业务使用时,用实际的Traits类型实例化HandlerT即可 template<concepts::Traits TraitsT> using CurrentHandler = HandlerT<TraitsT>; };
内容的提问来源于stack exchange,提问作者Moshe Groot
相关产品推荐
相关产品推荐

