Кто-нибудь знает о несоответствии ниже? где gcc и clang ведут себя по-разному, когда задействованы концепции С++ 20.
В основном объявленный concept
в gcc может найти мой пользовательский operator==
, даже если он объявлен после concept
, но это не относится к простым функциям (с именами, определенными пользователем). Принимая во внимание, что concept
в clang в обоих случаях не может найти ни одно из моих объявлений, если они не объявлены перед concept
.
И главный вопрос: "У какого компилятора правильное поведение?"
ПРИМЕЧАНИЕ: оба компилятора работают нормально, если все мои объявления объявлены перед 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;
}
Кланг прав. gcc просто имеет проблемы с поиском операторов.
В обеих ваших концепциях мы ищем имя: operator==
в одном случае и compare
в другом. Сначала мы выполняем обычный неквалифицированный поиск, а затем выполняем поиск, зависящий от аргумента.
В обоих случаях оба поиска не должны ничего найти: нет жизнеспособных кандидатов, найденных неквалифицированным поиском (ничего не объявлено перед concept
, которые мог бы найти неквалифицированный поиск), и нет жизнеспособных кандидатов, найденных ADL (мы просматриваем только связанные пространства имен, что быть std
, но ваши кандидаты не в std
, они в глобальном пространстве имён: ::
). При отсутствии кандидатов обе проверки концепций должны провалиться.
Однако gcc все равно находит ваш operator==
. Хотя не должно, это неправильно.
Вот почему:
ПРИМЕЧАНИЕ: оба компилятора работают нормально, если все мои объявления объявлены перед концепцией.
Потому что теперь обычный неквалифицированный поиск находит рассматриваемых кандидатов.