user6245072 user6245072 - 1 month ago 11
C++ Question

How to make all instances of a template function friends of a class?

I have a class which is meant to be constructed only by some factory functions and not directly.

These factory function all have the same name, but are differentiated based on the enum value passed as their template argument (see the first method explained in this answer).

An example of those functions:

enum Tag {
foo,
bar,
tag3
};

//declarations
template <Tag>
myClass Factory(int, char);

template <Tag>
myClass Factory(std::string, float);

//definitions
template <>
myClass Factory<foo>(int x, char y) {...}

template <>
myClass Factory<bar>(std::string x, float y) {...}

//as you can see, this way I can have functions with the same
//arguments that do different things with different tags:
template <>
myClass Factory<tag3>(int x, char y) {...}


How can I make all those functions friends of the class all at once so that they can use its private constructor?

I.e. in the example above I would want to have both
Factory<foo>
,
Factory<bar>
and
Factory<tag3>
to have access to myClass's private members, but I don't want to list each of those. How can I do it?

Answer

Making a function template or a class template friends with your class:

template<class T>
class foo;

// forward declaration of the function. not really needed
template<class T>
void fun(T);

class myclass
{
private:
    int a;

    template<class T> friend class foo;
    template<class T> friend void fun(T); 
    // the above line declares foo<T>(T) to be friend of myclass
};

// the specializations definitions follow below
template<> void fun<int>(int i)
{
    myclass m;
    m.a = i; 
}

template<> void fun<char>(char c)
{
    myclass m;
    m.a = int(c);
}
// as you can see, they both can use the private members of myclass.