如何修改C++ Concept以支持参数包兼容空大括号与指定谓词?
解决方案
问题的核心是传递{}作为参数时,编译器无法推断对应的模板参数类型,导致参数包推断不完整。要实现参数包同时接受符合要求的谓词和空大括号{},可以通过以下两种方式修改concept:
方案1:定义专用占位符类型
这种方式更严谨,仅允许指定的占位符类型通过concept检查:
- 先定义一个可被空初始化列表构造的占位符类型:
struct Empty { // 允许空大括号{}直接初始化该类型 Empty(std::initializer_list<int>) {} };
- 修改concept,使其同时接受谓词和Empty类型:
template<typename V> concept myconcept = std::predicate<std::remove_cvref_t<V>, int> || std::same_as<std::remove_cvref_t<V>, Empty>;
当传递{}作为参数时,编译器会自动推断对应的模板参数为Empty,该类型满足concept,参数包即可完整推断。
方案2:通用匹配空初始化列表
如果不需要严格限制占位符类型,可以让concept匹配所有能被空初始化列表构造的类型:
template<typename V> concept myconcept = std::predicate<std::remove_cvref_t<V>, int> || requires { // 检查类型是否可被空初始化列表构造 std::remove_cvref_t<V>(std::initializer_list<int>{}); };
这个方案会匹配所有拥有std::initializer_list<int>构造函数的类型,空大括号{}会被自动推断为对应类型,同样能解决参数包推断不完整的问题。
内容的提问来源于stack exchange,提问作者IlyaZhuravlev
相关产品推荐
相关产品推荐

