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

带trailing requires子句的类外模板成员函数定义合法形式问询

C++类成员模板trailing requires子句中嵌套类型的引用问题

以下代码展示了类A包含嵌套类型B,其模板成员函数的trailing requires子句引用嵌套类型B,并在类外定义这些函数的场景:

template <typename X, typename Y>
concept C = true;

struct A
{
    struct B {};

    template <typename T>
    void f1()
    requires C<T, A::B>;

    template <typename T>
    void f2()
    requires C<T, A::B>;

    template <typename T>
    void f3()
    requires C<T, B>;

    template <typename T>
    void f4()
    requires C<T, B>;
};

template <typename T>
inline void A::f1()
requires C<T, A::B> {}

template <typename T>
inline void A::f2()
requires C<T, B> {}

template <typename T>
inline void A::f3()
requires C<T, A::B> {}

template <typename T>
inline void A::f4()
requires C<T, B> {}

int main()
{
    A{}.f1<A::B>();
    A{}.f2<A::B>(); 
    A{}.f3<A::B>();
    A{}.f4<A::B>();
}

我无法找到或明确理解以下问题的权威标准表述:

  • trailing requires子句是否可像尾随返回类型那样,无需显式限定即可引用嵌套类型
  • 合规的编译器实现应接受f2、f3、f4中的哪些定义

在C++标准草案中,最接近的内容来自[temp.mem]章节:

在类模板定义外部定义的类模板成员模板,应指定与类模板等效的模板头,后跟与成员模板等效的模板头(13.7.6.1)。

其中13.7.6.1引用了[temp.over.link]第7段:

若两个函数模板在同一作用域中声明、同名、具有等效的模板头,且返回类型、参数列表和trailing requires子句(若有)使用上述规则比较涉及模板参数的表达式后等效,则这两个函数模板等效。

对于requires子句本身,等效性由以下规则指定:

两者均有requires子句,且对应的约束表达式等效。

在其他语境下,我认为f1至f4的所有约束形式在形式上都是等效的,但我对标准的熟悉程度不足以自行得出结论。

在编译器实现方面,clang和gcc似乎一致接受所有定义,而MSVC的表现有所不同,且近期发生了行为变化:

函数gcc 12.2clang 15.0.0MSVC 19.33MSVC Latest (19.34?)
f1接受接受接受接受
f2接受接受错误C2244:无法将函数定义与现有声明匹配错误C2244:无法将函数定义与现有声明匹配
f3接受接受错误C2244:无法将函数定义与现有声明匹配错误C2244:无法将函数定义与现有声明匹配
f4接受接受接受错误C2065:未声明标识符'B'

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 18:03:18