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

Clang与GCC对模板构造函数继承的解析差异问题问询

问题:Clang与GCC对继承构造函数的解析分歧

不知为何,Clang拒绝编译以下看似正确的代码,而GCC可以编译通过:

#include <cstdio>
#include <utility>
#include <concepts>

template <typename T>
struct Wrapper {
    T val;
};


template <typename T>
struct Base {
    template <typename U> requires std::is_same_v<U, Wrapper<T>>
    Base(U&&) { puts("Base constructor called"); }
};


template <typename T>
struct S : Base<T> {
    using B = Base<T>;

    using B::B;

    template <typename U> requires std::is_constructible_v<T, U>
    S(U&& v)
        : B( Wrapper<T>{ T(v) } ) { puts("S constructor called"); }
};


int main()
{
    // 按预期调用S的构造函数
    S<int> a(10);

    // GCC下按预期调用Base的构造函数,Clang编译失败
    S<int> b(Wrapper<int>{1});
}

这段代码使用了C++20 Concepts语法,即使改用SFINAE(包括typename = std::enable_if_t<...>和std::enable_if_t<..., bool> = true两种形式),结果仍然一致:GCC正常编译,Clang报错。

有意思的是,只要做以下任一修改,Clang就能正常编译:

  • 移除Base类构造函数的转发引用(&&)
  • 移除派生类S构造函数的转发引用(&&)
  • 给任一构造函数添加默认参数

这看起来像是Clang认为这两个构造函数的签名相同,从而隐藏了基类的构造函数。根据cppreference关于using声明与继承构造函数的说明:

与其他非静态成员函数的using声明一样,若继承的构造函数与派生类的某个构造函数签名匹配,会被派生类中的版本隐藏,无法被查找。

但如果把基类的构造函数直接移到派生类中,代码却能正常编译——这说明二者的签名其实并不匹配(否则会出现重声明错误)。那么这到底是Clang的Bug,还是我对C++相关规则存在误解?

Clang的报错信息如下:

foobar.cpp:37:12: error: no matching constructor for initialization of 'S<int>'
    S<int> b(Wrapper<int>{1});
           ^ ~~~~~~~~~~~~~~~
foobar.cpp:19:8: note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'Wrapper<int>' to 'const S<int>' for 1st argument
struct S : Base<T> {
       ^
foobar.cpp:19:8: note: candidate constructor (the implicit move constructor) not viable: no known conversion from 'Wrapper<int>' to 'S<int>' for 1st argument
struct S : Base<T> {
       ^
foobar.cpp:25:5: note: candidate template ignored: constraints not satisfied [with U = Wrapper<int>]
    S(U&& v)
    ^
foobar.cpp:24:36: note: because 'std::is_constructible_v<int, Wrapper<int> >' evaluated to false
    template <typename U> requires std::is_constructible_v<T, U>
                                   ^
1 error generated.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 09:13:19