C++20中该代码示例是否合规?是否存在模板实参推导歧义?
代码是否符合C++20标准,是否应因推导歧义被拒绝?
以下代码在不同编译器中表现不一致:
template<typename...> struct s { s(int) requires true {} s(int) {} }; static_assert(not noexcept(s{{}})); // Clang报错,GCC、MSVC通过
Clang的错误信息:
<source>:6:28: error: ambiguous deduction for template arguments of 's' 6 | static_assert(not noexcept(s{{}})); | ^ <source>:3:5: note: candidate function [with $0 = <>] 3 | s(int) requires true {} | ^ <source>:4:5: note: candidate function [with $0 = <>] 4 | s(int) {} | ^
原因分析
根据CWG Issue 2628的内容,C++20标准目前并未规定要将构造函数的requires子句传播到隐式生成的推导指南。这导致编译器处理这段代码时出现行为分歧:Clang判定存在推导歧义,而GCC和MSVC则接受该代码。
替代方案
可以通过提供用户自定义推导指南消除歧义:
template<typename...> requires true s(int) -> s<>; template<typename...> s(int) -> s<>;
注意,针对这个特定示例,仅写推导指南s(int) -> s<>;也能生效——因为用户自定义推导指南的优先级高于隐式生成的推导指南。这里需要在错误报告质量和代码冗余度之间做权衡。
内容的提问来源于stack exchange,提问作者303
相关产品推荐
相关产品推荐

