涉及c++20概念时gcc和clang行为不一致
Inconsistent behavior between gcc and clang when c++20 concepts are involved
有人知道下面的不一致吗?其中 gcc 和 clang 在涉及 c++20 概念 时表现不同。
基本上在 gcc 中声明的 concept
能够找到我的自定义 operator==
即使它是在 concept
之后声明的,但是它普通函数不是这种情况( 用户定义的名称 )。而 clang 中的 concept
在这两种情况下都无法找到我的任何声明,除非它们在 concept
.
之前声明
主要问题是:“哪个编译器的行为正确?”
注意: 如果我的所有声明都在 concept
.
之前声明,那么两个编译器都可以正常工作
输出: /// gcc-10.2 和 gcc-11
EqComparable=1
Comparable=0
输出: /// clang-11 and clang-12
EqComparable=0
Comparable=0
#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.
因为现在常规的不合格查找会找到有问题的候选人。
有人知道下面的不一致吗?其中 gcc 和 clang 在涉及 c++20 概念 时表现不同。
基本上在 gcc 中声明的 concept
能够找到我的自定义 operator==
即使它是在 concept
之后声明的,但是它普通函数不是这种情况( 用户定义的名称 )。而 clang 中的 concept
在这两种情况下都无法找到我的任何声明,除非它们在 concept
.
主要问题是:“哪个编译器的行为正确?”
注意: 如果我的所有声明都在 concept
.
输出: /// gcc-10.2 和 gcc-11
EqComparable=1 Comparable=0
输出: /// clang-11 and clang-12
EqComparable=0 Comparable=0
#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.
因为现在常规的不合格查找会找到有问题的候选人。