#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==
. Однако этого не должно быть, это неверно.
Вот почему:
ОБРАТИТЕ ВНИМАНИЕ, ЧТО: оба компилятора работают нормально, если все мои объявления объявлены перед концепцией.
Потому что теперь регулярный неквалифицированный поиск находит соответствующих кандидатов.