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

使用concept是否允许对非静态成员函数使用decltype?

C++中decltype(T::func)在concept中的合法性疑问

我了解到对于拥有非静态成员函数func的类X,C++标准不允许编写decltype(X::func),按预期下面的程序应该报错(比如提示“invalid use of non-static member function”),但实际在GCC、Clang、MSVC三大编译器中都能编译通过:

#include <iostream>
#include <type_traits> 
#include <concepts>

template < typename T >
concept test = std::same_as <decltype(T::func), int(int) >;

struct D
{
    int func(int);
};

int main()
{ 
    std::cout << test<D>;      
}    

查阅标准中expr.prim.id相关条款后,该程序似乎属于格式错误,编译器应当发出诊断,但目前没有编译器报错。想请教:像示例中这样在concept里使用decltype(T::func)是否让程序合法?还是说程序仍属格式错误,只是三大编译器都存在实现问题?


结论

程序仍属于格式错误,三大编译器的行为不符合C++标准要求。

标准依据

根据C++标准中关于expr.prim.id(主表达式中的标识符)的规定:引用非静态成员函数时,不能直接用X::func这种形式来获取其类型——非静态成员函数的标识符没有独立的函数类型,它必须与具体的类实例关联(除非是在声明指向成员函数的指针的语境中)。

decltype(T::func)这种写法,本质是试图获取未绑定的非静态成员函数的类型,这在标准中是明确禁止的,属于格式错误(ill-formed),编译器必须发出诊断信息。

编译器通过的原因

这属于编译器的实现疏漏。尽管concept是C++20的新特性,但它并未改变非静态成员函数的引用规则。编译器可能在处理concept的约束表达式时,错误地将decltype(T::func)推导为普通函数类型,或是放宽了对非静态成员函数标识符的检查逻辑,但这并不符合标准的要求。

正确的写法

如果要检查类T是否拥有签名为int(int)的非静态成员函数func,应当使用指向成员函数的指针类型来匹配:

template <typename T>
concept test = std::same_as<decltype(&T::func), int (T::*)(int)>;

这种写法既符合标准规定,也能正确完成类型检查。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 01:02:14