C++20约束特化模板在Clang/MSVC实例化失败仅GCC可编译问题咨询
问题原因
你的代码触发了GCC的非标准扩展,并不符合C++标准的要求,因此仅能在GCC下编译通过,Clang和MSVC执行标准规则所以编译失败。
核心问题点
- 标准C++要求模板模板参数匹配时,参数数量必须严格对齐,除非使用可变参数模板形参。你声明的
template<typename, typename> typename Mapped_Container只能匹配恰好2个模板参数的模板,而std::map实际包含4个模板参数(后2个为比较器、分配器,带默认值),std::vector包含2个模板参数(第2个为分配器,带默认值),都不符合你定义的模板形参要求。 - GCC默认开启了非标准扩展,允许将带默认模板参数的模板匹配到参数更少的模板模板参数,因此你的代码在GCC下可以正常编译,Clang和MSVC默认执行标准规则,找不到对应的特化实现,就会报未定义模板、特化失败的错误。
修复方案
将模板模板参数改为可变参数形式,兼容带默认参数的标准容器,修正后的特化代码如下:
// 键值型容器特化 template<template<typename> typename Wrapper, template<typename...> typename Mapped_Container, typename Key, typename Value, typename... Args> requires std::is_same_v< typename Mapped_Container<Key, Value, Args...>::value_type, std::pair<const typename Mapped_Container<Key, Value, Args...>::key_type, typename Mapped_Container<Key, Value, Args...>::mapped_type>> struct repack<Wrapper, Mapped_Container<Key, Value, Args...>> { using type = Mapped_Container<Wrapper<Key>, Wrapper<Value>, Args...>; }; // 单值型容器特化 template<template<typename> typename Wrapper, template<typename...> typename Unmapped_Container, typename Value, typename... Args> struct repack<Wrapper, Unmapped_Container<Value, Args...>> { using type = Unmapped_Container<Wrapper<Value>, Args...>; };
修改后的代码可在GCC、Clang、MSVC三个主流编译器下正常编译。
内容的提问来源于stack exchange,提问作者Ranoiaetep
相关产品推荐
相关产品推荐

