约束'C<T>'自依赖编译分歧:MSVC与GCC/Clang表现差异咨询
代码兼容性与合法性问题
我有一段代码在Visual Studio中能正常编译(但运行时会触发栈溢出),但GCC和Clang直接拒绝编译。简化后的示例代码如下:
struct A { void f( const int & ) {} template <typename T, typename = decltype( g( std::declval<const T&>(), std::declval<A&>() ) )> void f( const T& t ) { g( t, *this ); } }; template <typename T> concept C = requires ( const T& t, A & a ) { { a.f( t ) }; }; template <C T> void g( const T& t, A & a ) { a.f( t ); } int main() { A a; g( 1.f, a ); }
代码逻辑与表现差异
这段代码的核心设计:
- 结构体
A包含两个重载的f方法:一个是接收const int&的非模板版本,另一个是函数模板,仅当全局函数g存在匹配重载时(通过SFINAE机制)才会被启用。 - 全局函数模板
g通过概念C<T>做约束,要求A的对象可以调用f处理T类型的参数。
当调用g(1.f, a)时:
- GCC和Clang直接报错:
error: satisfaction of atomic constraint 'requires(const T& t, A& a) {{a->A::f(t)};} [with T = T]' depends on itself
- MSVC的表现:
- 能编译通过,但运行时会因
g<float>与A::f<float, void>互相调用形成无限递归,最终导致栈溢出。 - 如果删除
A的非模板f方法,MSVC也会编译失败,提示约束不满足。
- 能编译通过,但运行时会因
疑问
请问这是MSVC的bug,还是程序本身属于非法代码,且编译器无需强制给出诊断?
内容的提问来源于stack exchange,提问作者Fedor
相关产品推荐
相关产品推荐

