将std::span作为模板模板参数时Clang编译失败的原因咨询
问题原因与解决方法
核心原因
std::span的实际模板定义是:
template <typename T, std::size_t Extent = std::dynamic_extent> class span;
它是一个双参数模板类,第二个参数带有默认值。
而你定义的模板模板参数:
template <template <typename> class S>
要求传入的是仅接受单个模板参数的类模板。
C++标准规定,模板模板参数匹配时,不会考虑模板参数的默认值——也就是说,即便std::span的第二个参数有默认值,它依然是双参数模板,不符合单参数模板模板参数的要求。
GCC在这里启用了非标准扩展,允许带有默认参数的多参数模板匹配单参数模板模板参数;而Clang严格遵循C++标准,因此拒绝编译你的代码。
修正方案
你可以修改模板模板参数,使其匹配std::span的双参数结构,或者使用可变参数模板模板参数来兼容任意参数数量的模板:
方案1:匹配双参数模板
#include <iostream> #include <span> #include <vector> std::vector v{1,2,3,4,5,6}; // 模板模板参数接受两个参数,第二个带默认值 template <template <typename, std::size_t = std::dynamic_extent> class S> S<int> GetSpan() { return v; } int main() { auto x = GetSpan<std::span>(); return 0; }
方案2:使用可变参数模板模板参数(更通用)
#include <iostream> #include <span> #include <vector> std::vector v{1,2,3,4,5,6}; // 可变参数模板模板参数,兼容任意参数数量的模板 template <template <typename...> class S> S<int> GetSpan() { return v; } int main() { auto x = GetSpan<std::span>(); return 0; }
内容的提问来源于stack exchange,提问作者aep
相关产品推荐
相关产品推荐

