Непоследовательное поведение между gcc и clang при использовании концепций С++20

Кто-нибудь знает о несоответствии ниже? где gcc и clang ведут себя по-разному, когда задействованы концепции С++20 .

В основном объявленный в gcc может найти мой пользовательский operator==даже если он объявлен после , но это не относится к простым функциям ( с именами, определенными пользователем ). Принимая во внимание, что in clang в обоих случаях не может найти ни одно из моих объявлений, если они не объявлены до .

И главный вопрос: "У какого компилятора правильное поведение?"

ЗАМЕЧАНИЕ: оба компилятора работают нормально, если все мои объявления объявлены до concept.

  • Вывод : /// gcc-10.2 и gcc-11

            EqComparable=1
    Comparable=0
    
  • Вывод : /// clang-11 и 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;
}

1 ответ

Кланг прав. gcc просто имеет проблемы с поиском операторов.

В обеих ваших концепциях мы ищем имя: в одном случае и compareв другом. Сначала мы выполняем обычный неквалифицированный поиск, а затем выполняем поиск, зависящий от аргумента.

В обоих случаях оба поиска не должны ничего находить: нет подходящих кандидатов, найденных неквалифицированным поиском (ничего не объявлено перед поиском). concepts, которые мог бы найти неквалифицированный поиск), и ADL не находит жизнеспособных кандидатов (мы просматриваем только связанные пространства имен, которые были бы , но ваши кандидаты не находятся в std, они находятся в глобальном пространстве имен: ::). При отсутствии кандидатов обе проверки концепций должны провалиться.

Однако gcc просто находит ваш operator==тем не мение. Хотя не должно, это неправильно.

Вот почему:

ПРИМЕЧАНИЕ: оба компилятора работают нормально, если все мои объявления объявлены перед концепцией.

Потому что теперь обычный неквалифицированный поиск находит рассматриваемых кандидатов.

Другие вопросы по тегам