Для C ++ предназначены 20 концепций, и некоторые компиляторы уже предоставляют некоторые ранние реализации для этого.Мы столкнулись с некоторой проблемой с объявлениями друзей класса шаблона, где параметры имеют ограничения.После недолгих поисков и попыток найти что-либо в проекте стандарта и связанных с ним документах мы не понимаем, что можно и / или исправить.
Мы попробовали стандартные идеи, которые можно было бы найти, чтобы найти решение, ноне удалось найти ничего, что могло бы работать для всех опробованных компиляторов или официального ответа из стандарта, что может быть просто неудачей при чтении правильных результатов поиска.
Мы пытаемся создать друга.связь между классом шаблона и самим собой делает все другие экземпляры шаблона другом.
Исходная версия выглядит как
template <typename T> concept Constraint = true;
template <Constraint T>
class A { };
struct B {
template <typename>
friend class A;
};
Компилируется в gcc, но не в clang и не в последнем предварительном просмотре MSVC.компилятор
Следующая попытка - использовать ограничения в объявлении друга, то есть
template <typename T> concept Constraint = true;
template <Constraint T>
class A { };
struct B {
template <Constraint>
friend class A;
};
, который выглядит как естественный способ сделать это, потому что в любом случае друга можно создать только с выполнением ограничений..
Это проходит с GCC, Clang не счастлив оТаким образом, MSVC согласен с объявлением, но завершается неудачно, когда кто-то пытается его использовать.Он жалуется на то, что ограничения не выполняются, что неверно.
Приходится также добавлять некоторые идентификаторы классов в объявление друга, например:
template <typename T> concept Constraint = true;
template <Constraint T>
class A { };
struct B {
template <Constraint U>
friend class A;
};
Это приводит к тому жекак и предыдущая попытка.До сих пор мы не смогли придумать синтаксис (если это вообще возможно), который действительно работает.Если кто-то не использует ограничения и использует трюки SFINAE и использует просто «typename», он работает, как и ожидалось.
Было бы полезно, если бы у кого-нибудь была идея, как это исправить, используя реальные возможности C ++ 20или указатель, где эта ситуация фактически описана.Мы знаем, что мы могли бы просто использовать сеттеры и геттеры, но это не главное.