如何将友元声明用于具有约束的模板类
How to use friend declaration for template class with constraints
对于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 可以声明,但在实际尝试使用它时失败。它抱怨说,这些限制没有得到满足,这是不正确的。
人们还想出将一些类 ID 放入朋友声明中,即
template <typename T> concept Constraint = true;
template <Constraint T>
class A { };
struct B {
template <Constraint U>
friend class A;
};
这会导致与上一次尝试相同的结果。 到目前为止,我们还无法提出实际有效的语法(如果可能的话(。 如果不使用约束并使用 SFINAE 技巧并仅使用"类型名",则它可以按预期工作。
如果有人知道如何使用实际的 C++20 功能或实际描述这种情况的指针来修复它,将不胜感激。我们知道我们可以只使用二传手和接球手,但这不是重点。
我很确定这是正确的版本(即您的第二或第三选项(:
template <typename T> concept Constraint = true;
template <Constraint T>
class A { };
struct B {
template <Constraint> friend class A;
};
这应该与A
的所有专业交朋友。typename
会不正确,因为这与A
声明不匹配。我认为我们对此没有具体的措辞,但这似乎是明确的意图。
gcc 和 clang 都接受这个版本(demo(,而编译器资源管理器上的 MSVC 版本根本没有实现概念。
- C++模板来检查友元函数的存在
- 模板类无法识别友元运算符
- 如何使用单独文件中的派生类访问友元函数对象
- 模板化的类和友元函数
- 为什么创建友元类的实例会导致"undefined reference to"错误?
- 如何在嵌套类中正确使用友元声明?
- 友元函数无法访问私有数据成员 (c++)
- 继承和友元函数,从基类访问受保护的成员
- 将子类方法声明为基类的友元
- 如何在友元函数中使用静态成员而不添加前缀 [类名]::
- 在将函数声明为友元时,尖括号的含义是什么?
- 在模板类之外定义友元函数的正确方法是什么?
- 2个模板化类的非模板友元函数未定义引用错误
- 友元方法作为常量
- C++ 友元函数和私有构造函数
- 使第二个类的构造函数成为第一个类中的友元函数
- 在为嵌套类定义行外友元时,我真的必须打破封装吗?
- 未定义的类模板不会实例化以检查友元函数
- C++类中的友元函数有问题?
- 如何将友元声明用于具有约束的模板类