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