C++20 concept结合delete关键字移除operator<<重载相关问题咨询
问题解答
问题1:= delete标记的重载生效时机与影响范围
- 生效时机:重载决议阶段生效,和concept实例化时机无关。当你使用满足
HasLogMethodReturningReferenceToSelf约束的类型作为operator<<左操作数、且右操作数无法转换为std::string时,这个被删除的重载会进入候选集。如果此时没有比它更匹配的自定义operator<<重载,它就会被选中,直接触发编译错误,阻止隐式转换生成的非法重载被调用。 - 对现有代码的影响:不会破坏现有合法代码。因为自定义的
operator<<重载的特例化程度比这个通用模板更高,重载决议时会优先匹配你自己实现的合法重载,只有当没有对应合法重载时才会命中这个被删除的版本,相当于提前拦截非法调用,不会影响已经存在的正确逻辑。
问题2:合并concept后递归编译错误的原因
递归的核心是约束检查和重载决议构成了循环依赖:
- 把
operator<<的检查合并到Loggable概念后,被删除的operator<<重载的约束变为T satisfies Loggable。 - 当编译器要判断某个类型
T是否满足Loggable时,需要先检查v << "string literal"这类表达式是否合法,此时会检索所有可用的operator<<候选,其中就包含你定义的这个被删除的模板重载。 - 要判断这个模板重载能不能匹配当前的
<<调用,编译器需要先确认T是否满足Loggable约束,这又回到了上一步的检查逻辑,形成无限递归,最终超出模板实例化的最大深度报错。
而拆分concept的写法不会触发递归,是因为被删除的重载用的约束HasLogMethodReturningReferenceToSelf只检查log()方法是否存在,完全不涉及operator<<的检查,不会形成循环依赖。
内容的提问来源于stack exchange,提问作者K. Koovalsky
相关产品推荐
相关产品推荐

