C++推导指南在GCC、MSVC编译通过但Clang报错,求判定合规编译器
C++推导指南的编译器分歧:Clang拒绝的代码是否符合标准?
我在学习C推导指南时编写了一段代码,它能在GCC和MSVC中编译通过,但被Clang直接拒绝,想明确哪个编译器的行为符合C标准。
代码示例
#include <vector> #include <array> #include <memory> struct Coord { int x, y; }; template<int N, int D = 0 > class CoordArray { public: CoordArray(const Coord(&ref)[N]) {} }; template<int D, int N> CoordArray() -> CoordArray<N, D>; CoordArray<3> myCoordArray{{{2, 1}, {4, 1}, {6, 1}}}; // Clang拒绝,GCC/MSVC接受 CoordArray myCoordArray2{{{2, 1}, {4, 1}, {6, 1}}}; // Clang拒绝,GCC/MSVC接受
Clang报错信息
<source>:17:24: error: deduction guide template contains template parameters that cannot be deduced 17 | template<int D, int N> CoordArray() -> CoordArray<N, D>; | ^ <source>:17:14: note: non-deducible template parameter 'D' 17 | template<int D, int N> CoordArray() -> CoordArray<N, D>; | ^ <source>:17:21: note: non-deducible template parameter 'N' 17 | template<int D, int N> CoordArray() -> CoordArray<N, D>; |
标准分析与结论
Clang的行为符合C++标准,问题出在你定义的推导指南上:
- 根据C++标准[over.match.class.deduct]的规定,推导指南的模板参数必须要么有默认实参,要么能从推导指南的函数参数类型中推导出来。
- 你编写的推导指南是无参构造形式,既没有参数可用于推导
D和N,这两个模板参数也没有默认值,完全无法确定取值,因此这个推导指南本身属于非法构造。 - GCC和MSVC接受这段代码属于编译器的非标准扩展行为,而Clang严格遵循标准,直接拒绝了非法的推导指南。
如果要让代码符合标准,要么给推导指南的模板参数添加默认值,要么删除这个多余的无参推导指南——你的类已有的构造函数已经支持推导N,D会自动使用类模板的默认值0。
内容的提问来源于stack exchange,提问作者user20562802
相关产品推荐
相关产品推荐

