You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++20模板推导分歧:b{d{}}构造的编译器行为差异咨询

C++20模板构造函数约束与类模板推导的编译器分歧解析

问题描述

我认为b{d{}}的构造应触发编译错误,因为b的模板构造函数受约束限制不可行。但GCC和MSVC接受该代码,推导b为b<int>而非b<d>,这与我理解的隐式推导指南template<typename T> b(T) -> b<T>不符。请问应信任哪个编译器?C++20标准对此行为有何规定?

代码示例

template<typename T>
struct b {
    b() = default;
    b(T) requires false {}
};
struct d : b<int> {};
inline constexpr auto z = b{d{}};

Clang报错信息

<source>:7:27: error: no matching constructor for initialization of 'b<d>'
    7 | inline constexpr auto z = b{d{}};
      |                           ^~~~~~
<source>:2:8: note: candidate constructor (the implicit copy constructor)
not viable: no known conversion from 'd' to 'const b<d>' for 1st argument
    2 | struct b {
      |        ^
<source>:2:8: note: candidate constructor (the implicit move constructor)
not viable: no known conversion from 'd' to 'b<d>' for 1st argument
    2 | struct b {
      |        ^
<source>:4:5: note: candidate constructor not viable: constraints not satisfied
    4 |     b(T) requires false {}
      |     ^
<source>:4:19: note: because 'false' evaluated to false
    4 |     b(T) requires false {}
      |                   ^
<source>:3:5: note: candidate constructor not viable: requires 0 arguments,
but 1 was provided
    3 |     b() = default;
      |     ^

解答

编译器正确性判定

GCC和MSVC的行为符合C++20标准,Clang在此场景下存在实现错误。

标准依据与行为解释

C++20标准中,类模板推导(CTAD)的候选函数集不仅包含用户定义构造函数对应的隐式推导指南,还包括类模板特化的隐式生成构造函数(如拷贝、移动构造函数)对应的推导指南:

  1. 对于b<T>的隐式拷贝构造函数b(const b<T>&),会生成对应的隐式推导指南:template<typename T> b(const b<T>&) -> b<T>。
  2. 当用d{}初始化b实例时,d作为b<int>的派生类,可以隐式转换为const b<int>&,因此上述拷贝构造函数对应的推导指南会推导出T=int。
  3. b<int>的拷贝构造函数不受requires false约束(该约束仅作用于用户定义的b(T)构造函数),因此这个推导路径是完全可行的。

Clang的错误在于,它仅考虑了用户定义构造函数b(T)对应的推导指南(推导出b<d>,但该构造函数因约束不可行),却遗漏了拷贝构造函数对应的推导路径,导致错误判定代码非法。

内容的提问来源于stack exchange,提问作者303

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 01:09:52