【问题标题】:How to use friend declaration for template class with constraints如何对具有约束的模板类使用友元声明
【发布时间】:2019-09-25 16:38:03
【问题描述】:

对于 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++ friend c++20 c++-concepts


    【解决方案1】:

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

    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 版本根本没有实现概念。

    【讨论】:

    • 感谢您的回答,这也是我的预期。我对 clang 声明感到惊讶,但我们无法使其适用于 clang。我们对 gcc 行为有了新的认识。 MSVC 支持最新预览版本中的概念,即如果使用选项 std:c++latest,则从 MSVC 19.3.0 预览 3 开始。尚未实现所有功能。这就是为什么还没有正式的 std:C++20 选项的原因。
    • 我刚刚看了你的回答,发现它与问题略有不同。
    • @H.Gutsche 它与问题有何不同?那么问题是什么?
    • 我刚刚看了你的答案,发现它与问题不同。我们不是想和另一个班级交朋友,而是想和自己交朋友,即如果你的 B 变成 A 会发生什么?朋友发生在它的朋友声明中。尝试是为当前正在声明的模板的未指定实例声明朋友。现在我完全糊涂了,因为我意识到目前的问题不是我问的问题。你编辑了吗??
    • @H.Gutsche 是的,我编辑了这个问题,使它由真实代码而不是随机点组成,使它成为一个更好的问题。 Bfriending AAfriending A 之间没有关系,正确的语法不会改变,两个编译器 still accept it
    猜你喜欢
    • 2013-09-18
    • 2016-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-05
    • 1970-01-01
    相关资源
    最近更新 更多