C++ Namespaces
This code gives constructor is inaccessible errors in createBar(...)Â when you try to compile it:
namespace foo{ class Bar{ protected: Bar(int n); int numBars; public: friend Bar * createBar(int n); }; Bar * createBar(int n); } using namespace foo; Bar::Bar(int n) : numBars(n) { } Bar* createBar(int n){ return new Bar(n); }
The code below is the solution to the problem:
namespace foo{ class Bar{ protected: Bar(int n); int numBars; public: friend Bar * createBar(int n); }; Bar * createBar(int n); } using namespace foo; Bar::Bar(int n) : numBars(n){ } Bar* foo::createBar(int n){ return new Bar(n); }
This is acutaly the same problem as if you tried to compile the program below, but in the program below you get linker errors instead:
#include <stdio.h> namespace foo{ int bar(int n); } using namespace foo; int bar(int n){ return n + 42; } int main () { printf("%i\n",foo::bar(5)); return 0; }
The only difference in the example with classes is that it fails to compile, rather than link. It's a rather obvious bug in retrospect, but the syptoms sent me looking for typos, rather than namespace errors. The root cause of confusion is that the "using namespace foo;" line lets you remove the "foo::" from the front of the bar constructor and any bar methods, so it is reasonable (but wrong) to apply the same logic to the factory function.
This bug happened because I was moving an existing global namespace class into a new namespace. Someone more experienced with namespaces probably would have caught the problem right away. This is also a good example of where trying to find the smallest program that reproduces your bug can be a useful tool. The original code had boost shared pointers all over the place, several typedefs, and a couple hundred lines of other stuff that was not relevant to the problem. Cutting that all away made identifying the problem very easy.

















