3

There is a post explaining that a template parameter can be declared as friend with the following syntax:

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

but what if in some scenarios A needs a fried and in others does not? Is it possible to make T an optional argument?

Is there a better solution than using some kind of FakeClass as T?

EDIT1: I found another solution:

    class B {};

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

    template <>
    class A<void> {
    };

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

but what if A is a complicated class with 300 lines of code? Is there an alternative solution without template specialization?

Alexey Starinsky
  • 3,699
  • 3
  • 21
  • 57
  • If A is complicated you could do one more layer of abstraction. You move all the implementation in an `A_Impl` class and jusyt inherit from it in both specializations of `A` – Petok Lorand Jul 25 '19 at 11:46

2 Answers2

7

I think befriending a dummy is the cleanest thing you can do, since you can't inherit or conditionally declare friends. You don't even need to create a new dummy type, since:

[class.friend§3]

If the type specifier in a friend declaration designates a (possibly cv-qualified) class type, that class is declared as a friend; otherwise, the friend declaration is ignored.

Which means that you can pretend to befriend int or even void and they'll play along just fine.

This advice is valid only within the limits of the C++ standard and is not intended as a real life guideline. The poster declines any and all responsibilities concerning the application of the advice.

Quentin
  • 62,093
  • 7
  • 131
  • 191
0

Try this

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                                                                                                                                                 
};
Zang MingJie
  • 5,164
  • 1
  • 14
  • 27