基于C++17的带enable_if与is_constructible的可变参数构造器问题
问题:实现可隐式推导的PathToObject模板构造函数
背景
我定义了一个名为NameAndTag的类,它拥有以下构造函数:
NameAndTag(); NameAndTag(std::string name_or_tag); NameAndTag(boost::uuids::uuid tag) : Tag(tag) {}
需求
需要实现另一个类PathToObject的模板构造函数,使其能接受任意数量、可用于构造NameAndTag的参数,且模板类型可隐式推导。
尝试的两种方案及问题
方案一
代码如下:
template<typename... NameOrTag> PathToObject(std::enable_if_t< std::is_constructible_v<NameAndTag, NameOrTag> , NameOrTag&&>... obj_path);
编译器无法推导NameOrTag的类型,报错提示传入参数过多,而模板未接收参数。
方案二
尝试简化类型推导,代码如下:
template<typename... NameOrTag> PathToObject(NameOrTag&&... obj_path, std::enable_if_t< std::conjunction_v < std::is_constructible_v<NameAndTag, NameOrTag>... > , bool> dummy = true);
混合可变参数包与可选参数后,编译器无法匹配PathToObject("name", uuid)的调用。
请问我的需求是否合理?如何在C++17环境下实现该功能?
问题已解决!
感谢各位帮助,相关补充如下:
- 已采纳的解决方案可运行演示示例已完成
- 我的实现代码已提交至对应仓库分支
- 补充说明:将模板文件拆分为
.h和.inl后,因模板定义处不能使用= nullptr,出现了“默认模板参数重定义”问题
编辑备注
- 开发环境限定为C++17;
- 根据要求补充了最小非工作示例;
- 修复了在线演示中缺失的
public:声明; - 添加了基于@Artyer解决方案的在线演示;
- 标记问题已解决。
内容的提问来源于stack exchange,提问作者André Caldas
相关产品推荐
相关产品推荐

