【问题标题】:Making an optional template parameter a friend?让可选模板参数成为朋友?
【发布时间】:2019-07-25 11:15:51
【问题描述】:

有一个post 解释模板参数可以用以下语法声明为友元:

template <typename T>
class A {
   friend T;
};

但是如果在某些情况下 A 需要油炸而在其他情况下不需要呢?是否可以使 T 成为可选参数?

有没有比使用某种 FakeClass 作为 T 更好的解决方案?

EDIT1:我找到了另一个解决方案:

    class B {};

    template <typename T>
    class A {
       friend T;
    };

    template <>
    class A<void> {
    };

int main()
{
    A<B> a1;
    A<void> a2;
    return 0;
}

但是如果 A 是一个有 300 行代码的复杂类呢?是否有没有模板专业化的替代解决方案?

【问题讨论】:

  • 如果 A 很复杂,您可以再做一层抽象。您将所有实现移动到 A_Impl 类中,并且 jusyt 在 A 的两个特化中都继承自它

标签: c++ c++17


【解决方案1】:

我认为与假人交朋友是你能做的最干净的事情,因为你不能继承或有条件地声明朋友。您甚至不需要创建新的虚拟类型,因为:

[class.friend§3]

如果友元声明中的类型说明符指定了一个(可能是 cv 限定的)类类型,则该类被声明为友元; 否则,朋友声明将被忽略

这意味着你可以假装与int 甚至void 成为朋友,他们会配合得很好。

此建议仅在 C++ 标准的限制范围内有效,并非作为现实生活指南。发帖人拒绝承担有关建议应用的任何和所有责任。

【讨论】:

  • A 是一个不错的解决方案。
  • 傻瓜也需要朋友。这不是一个坏建议。
【解决方案2】:

试试这个

template<typename... T>
class A {
    private:
        static const int i = 10;
    public:
        friend typename std::conditional<sizeof...(T) == 1, T..., void>::type;
};

class X {
    public:
        static const int a = A<X>::i;
};

class Y {
    public:
        static const int a = A<>::i; // error, A::i is private                                                                                                                                                 
};

【讨论】:

    猜你喜欢
    • 2010-10-16
    • 2017-08-08
    • 2013-09-28
    • 1970-01-01
    • 1970-01-01
    • 2021-06-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多