首页 > 解决方案 > 如何对具有约束的模板类使用友元声明

问题描述

对于 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 技巧并且只使用“typename”,它会按预期工作。

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

标签: c++friendc++20c++-concepts

解决方案


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

template <typename T> concept Constraint = true;

template <Constraint T>
class A { };

struct B {
    template <Constraint> friend class A;
};

这应该与A. typename会有不正确的,因为这与 . 的声明不匹配A。我认为我们对此没有具体的措辞,但这似乎是明确的意图。

gcc 和 clang 都接受这个版本(demo),并且 compiler-explorer 上的 MSVC 版本根本还没有实现概念。


推荐阅读