根据C++标准,对不完整类型使用sizeof(T)属于合法SFINAE替换失败吗?
回答
核心结论
这个用法是C++标准明确定义的可靠行为,不是编译器非标准扩展,可放心使用。
标准规则解释
你提到的sizeof不得对不完整类型应用的规定确实存在,但它和SFINAE规则并不冲突:
- 普通非模板语境下对不完整类型用
sizeof,确实属于程序ill-formed,编译会直接报错。 - 但在模板参数替换的直接上下文中出现的这类错误,符合SFINAE的触发条件:不会导致整个程序格式错误,只会让当前有问题的模板候选被丢弃,匹配其他可行候选。
decltype(sizeof(T))的场景恰好属于替换直接上下文的错误:当T不完整时,sizeof(T)求值失败的时机正好在模板参数替换阶段,完全符合SFINAE的适用规则,所以配合std::void_t实现完整类型检测是完全合规的。
不同C++版本的差异
- C11、C14:相关规则已经完备,所有符合标准的编译器都支持该用法
- C++23:标准库正式新增了
std::is_complete_v类型特征,其底层实现就是基于该SFINAE机制,相当于官方直接认可了这个用法的合法性。
至于Raymond Chen当年的顾虑,是因为2019年前后业界对该用法的合规性存在少量争议,后续C++标准委员会已经通过明确的规则解释和新增库特性的方式消弭了该争议,现在不存在合法性问题。
内容的提问来源于stack exchange,提问作者Bitwize
相关产品推荐
相关产品推荐

