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

#c #c 20 #c -concepts

#c #c 20 #c -концепции

Вопрос:

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

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

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

ОБРАТИТЕ ВНИМАНИЕ, ЧТО: оба компилятора работают нормально, если все мои объявления объявлены перед a 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::stringamp;, const std::regexamp; )
{
    return {"hello"};
}

std::string compare( const std::stringamp;, const std::regexamp; )
{
    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:

Clang верен. у gcc просто есть проблемы с поиском операторов.

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

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

Однако gcc все равно находит ваш operator== . Однако этого не должно быть, это неверно.

Вот почему:

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

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