为何C++20 Concepts会触发循环约束错误,而传统SFINAE不会?
传统SFINAE与C++20 Concepts在通用回退operator<<中的行为差异
我在实现一个**仅当参数依赖查找(ADL)未找到现有自定义operator<<时才启用的通用回退operator<<**时,发现传统SFINAE(结合type_traits和std::void_t)与C++20 Concepts的行为存在意外差异。
传统SFINAE实现(可正常工作)
基于特征检测的is_std_streamable可以正常完成需求,定义如下:
template <class T, class = void> struct is_std_streamable : std::false_type {}; template <class T> struct is_std_streamable<T, std::void_t<decltype(std::declval<std::ostream&>() << std::declval<const T&>())>> : std::true_type {};
C++20 Concepts实现(触发循环约束错误)
基于Concepts的StdStreamable检测定义为:
template <class T> concept StdStreamable = requires(const T t, std::ostream& os) { { os << t } -> std::same_as<std::ostream&>; };
通用回退operator<<的代码如下(requires子句为注释状态):
template <StdPrintable T> // requires(!StdStreamable<T>) // requires(!is_std_streamable<T>::value) std::enable_if_t<!is_std_streamable<T>::value, std::ostream&> operator<<(std::ostream& os, T const& val) { ... }
当启用基于Concepts的requires(!StdStreamable<T>)子句时,GCC和Clang都会生成循环约束错误:
error: satisfaction of constraint 'StdStreamable
' depends on itself
核心疑问
我理解相关表达式可能存在循环依赖,但为什么Concepts会触发该问题,而传统SFINAE却不会?这种行为是C++标准规定的、Concepts的已知限制,还是编译器bug?
内容的提问来源于stack exchange,提问作者Petr Filipský
相关产品推荐
相关产品推荐

