【问题标题】:Inconsistent behavior between gcc and clang when c++20 concepts are involved涉及 c++20 概念时 gcc 和 clang 之间的行为不一致
【发布时间】:2021-04-02 23:30:25
【问题描述】:

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

gcc 中声明的 concept 基本上可以找到我的自定义 operator==,即使它是在 concept 之后声明的,但对于普通函数来说并非如此(使用用户定义的名称)。而 clang 中的 concept 在这两种情况下都无法找到我的任何声明,除非它们在 concept 之前声明。

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

注意:如果我的所有声明都在 concept 之前声明,则两个编译器都可以正常工作。

  • 输出: /// gcc-10.2gcc-11

    EqComparable=1
    Comparable=0
    
  • 输出:/// clang-11clang-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;
}

【问题讨论】:

    标签: c++ c++20 c++-concepts


    【解决方案1】:

    Clang 是正确的。 gcc 只是在查找运算符方面存在问题。

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

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

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

    这就是为什么:

    注意:如果我的所有声明都在概念之前声明,则两个编译器都可以正常工作。

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

    【讨论】:

      猜你喜欢
      • 2014-04-11
      • 2020-09-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-17
      • 2011-07-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多