涉及c++20概念时gcc和clang行为不一致

Inconsistent behavior between gcc and clang when c++20 concepts are involved

有人知道下面的不一致吗?其中 gccclang 在涉及 c++20 概念 时表现不同。

基本上在 gcc 中声明的 concept 能够找到我的自定义 operator== 即使它是在 concept 之后声明的,但是它普通函数不是这种情况( 用户定义的名称 )。而 clang 中的 concept 在这两种情况下都无法找到我的任何声明,除非它们在 concept.

之前声明

主要问题是:“哪个编译器的行为正确?”

注意: 如果我的所有声明都在 concept.

之前声明,那么两个编译器都可以正常工作
#include <iostream>
#include <cstdlib>
#include <string>
#include <regex>

template< typename T1, typename T2 >
concept EqualityComparable = requires( T1 t1, T2 t2 ) { t1 == t2; };

template< typename T1, typename T2 >
concept Comparable = requires( T1 t1, T2 t2 ) { compare(t1,t2); };

std::string operator==( const std::string&, const std::regex& )
{
    return {"hello"};
}

std::string compare( const std::string&, const std::regex& )
{
    return {"hello"};
}

int main()
{    
    std::cout << "EqComparable=" << EqualityComparable<std::string, std::regex> << std::endl;
    std::cout << "Comparable=" << Comparable< std::string, std::regex > << std::endl;
}

叮当是正确的。 gcc 只是在查找运算符时遇到问题。

在您的两个概念中,我们都在查找名称:在一种情况下为 operator==,在另一种情况下为 compare。我们首先进行常规非限定查找,然后进行参数相关查找。

在这两种情况下,两次查找 应该 什么都找不到:不合格的查找没有找到可行的候选者(在 concept 之前没有声明不合格的查找可以找到) 并且 ADL 没有找到可行的候选者(我们只查看关联的命名空间,这将是 std,但你的候选者不在 std 中,它们在全局命名空间中::: ).没有候选人,两个概念检查都应该失败。

但是,gcc 无论如何都会找到您的 operator==。不过不应该,那是不正确的。

这就是为什么:

NOTE THAT: both compilers are working fine if all of my declarations declared before a concept.

因为现在常规的不合格查找会找到有问题的候选人。