概念约束模板函数调用的歧义

dri*_*low 5 c++ g++ c++-concepts c++20

我正在浏览 cppreference概念和约束指南,这似乎是目前唯一可用的指南。在“原子约束”下,他们给出了以下关于相同和非相同约束的示例(经过一些编辑以生成 MWE):

template<class T> concept bool Meowable = is_meowable<T>;
template<class T> concept bool BadMeowableCat = is_meowable<T> && is_cat<T>;
template<class T> concept bool GoodMeowableCat = Meowable<T> && is_cat<T>;
template<Meowable T> 
void f1(T){ std::cout<<"Called #1\n";} // #1
template<BadMeowableCat T> 
void f1(T){ std::cout<<"Called #2\n";} // #2

template<Meowable T> 
void f2(T){ std::cout<<"Called #3\n";} // #3
template<GoodMeowableCat T> 
void f2(T){ std::cout<<"Called #4\n";} // #4

void g(){
f1(0); // error, ambiguous: the is_meowable<T> in Meowable and BadMeowableCat forms distinct
// atomic constraints that are not identical (and so do not subsume each other)

f2(0); // OK, calls #4, more constrained than #3, GoodMeowableCat got its is_meowable<T> from Meowable
}
Run Code Online (Sandbox Code Playgroud)

但是,当我用 编译时g++ --std="c++1z" -fconcepts,输出是:

Called #2 
Called #4
Run Code Online (Sandbox Code Playgroud)

标准中是否有某个地方(不是在概念 TS 中,而是在 C++20 的采用版本中),在那里他们指定了这种行为(或保留规范定义),如果指南确实是正确的,那么这种行为背后的基本原理是什么?限制性规则?我会假设概念被标准化为基础的constexpr bool. 提前致谢!

这个问题是由不同IMHO这一个,因为从执行结果相矛盾导向,显然的标准,作为呼叫于f1应该是不明确的,因此导致一个编译器错误,但它并非如显然#2涵括#1. 如果不是这种情况,我认为值得澄清这种分歧的答案。