如何使用带约束的模板类的友元声明

H. *_*che 5 c++ friend c++-concepts c++20

对于 C++20 概念是有意的,并且一些编译器已经为其提供了一些早期实现。我们在模板类的友元声明中遇到了一些问题,其中参数有约束。经过一番深思熟虑并试图在标准草案和相关文件中找到任何内容后,我们并不知道什么是可能的和/或正确的。

我们已经尝试了人们为找到解决方案而提出的标准想法,但没有得出任何适用于所有尝试过的编译器的标准想法或标准的正式答案,这可能只是阅读正确的搜索结果时运气不好。

我们试图尝试在模板类与其自身之间创建友元关系,使模板的所有其他实例成为友元。

原始版本看起来像

template <typename T> concept Constraint = true;

template <Constraint T>
class A { };

struct B {
    template <typename>
    friend class A;
};
Run Code Online (Sandbox Code Playgroud)

这可以在 gcc 中编译,但不能在 clang 或最新的 MSVC 预览编译器中编译

下一个尝试是使用友元声明中的约束,即

template <typename T> concept Constraint = true;

template <Constraint T>
class A { };

struct B {
    template <Constraint>
    friend class A;
};
Run Code Online (Sandbox Code Playgroud)

这看起来是一种自然的方法,因为无论如何,朋友只能在满足约束条件的情况下被实例化。

这在 gcc 中通过了,clang 对此不满意,MSVC 可以接受该声明,但在实际尝试使用它时失败了。它抱怨约束没有得到满足,这是不正确的。

还提出将一些类 ID 放入朋友声明中,即

template <typename T> concept Constraint = true;

template <Constraint T>
class A { };

struct B {
    template <Constraint U>
    friend class A;
};
Run Code Online (Sandbox Code Playgroud)

这与之前的尝试结果相同。到目前为止,我们还无法想出一种真正有效的语法(如果可能的话)。如果不使用约束并使用 SFINAE 技巧并仅使用“typename”,它就会按预期工作。

如果有人知道如何使用实际的 C++20 功能或实际描述该情况的指针来修复它,我们将不胜感激。我们知道我们可以只使用 setter 和 getter,但这不是重点。

Bar*_*rry 2

我很确定这是正确的版本(即您的第二个或第三个选项):

template <typename T> concept Constraint = true;

template <Constraint T>
class A { };

struct B {
    template <Constraint> friend class A;
};
Run Code Online (Sandbox Code Playgroud)

这应该对所有专业化都很友好Atypename这将是不正确的,因为这与 的声明不匹配A。我认为我们对此没有具体的措辞,但这似乎是明确的意图。

gcc 和 clang 都接受这个版本(demo),而编译器浏览器上的 MSVC 版本根本还没有实现概念。