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?
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.