David Williams
David Williams

Reputation: 763

Template class with a friend function which is inside a nested namespace

I'm trying to create a template class with a friend function which is inside a nested namespace. It works fine if I remove all the namespaces or if I remove all the templatization. But with both in place it won't compile. Let's look at some code:

namespace MyNamespace
{
    // Forward declaration
    template <typename Type>
    class Container;

    // Forward declaration
    namespace AccessPrivateImplementation
    {
        template <typename Type>
        Type getValue(Container<Type>* container);
    }

    // Templatized class
    template <typename Type>
    class Container
    {
        friend Type AccessPrivateImplementation::getValue(Container<Type>* volume);
    private:
        Type value;
    };

    // Friend function inside a namespace
    namespace AccessPrivateImplementation
    {
        template <typename Type>
        Type getValue(Container<Type>* container)
        {
            return container->value;
        }
    }
}

int main(int argc, char* argv[])
{
    MyNamespace::Container<int> cont;
    MyNamespace::AccessPrivateImplementation::getValue(&cont);
    return 0;
}

The compiler (VS2010) tells me:

error C2248: 'MyNamespace::Container::value' : cannot access private member declared in class 'MyNamespace::Container'

Does anyone have any idea what I'm missing?

Upvotes: 1

Views: 945

Answers (2)

Shafik Yaghmour
Shafik Yaghmour

Reputation: 158469

As per my comment, if you declare the friend like so it will work:

friend Type AccessPrivateImplementation::getValue<>(Container<Type>* volume);
                                                 ^^

Upvotes: 1

Andy Prowl
Andy Prowl

Reputation: 126432

The friend declaration inside the Container class template declares a friend non-template function getValue() that lives in the AccessPrivateImplementation namespace.

However, you haven't provided such a function. Instead, what you have in the AccessPrivateImplementation namespace is a function template, whose appropriate specialization you want to be friend of Container<T> (for a given T).

To achieve this, the declaration you need is:

friend Type AccessPrivateImplementation::getValue<>(Container<Type>* volume);
//                                               ^^

Here is a live example that shows your code compiling with the above fix.

Upvotes: 1

Related Questions