some_math_guy
some_math_guy

Reputation: 333

Friend classes across different namespaces not working and namespace is not recognized

I am having trouble with the use of friend class in C++ I am forward declaring the friend class and using the appropriate namespaces, so I don't know what is going on. Inside class MeshNamespace::Mesh , ReferenceElementNamespace::ReferenceElement 's members are still unable to access private members of the former. Besides in ReferenceElement.hpp, MeshNamespace identifier is not recognized.

If I forward-declare it as class Mesh; without the namespace it doesn't complain , but still doesn't work just as if there were no forward declaration at all;

//file ReferenceElement.hpp

namespace ReferenceElementNamespace {
    class MeshNamespace::Mesh; // ReferenceElement.hpp:27:9: error: use of undeclared identifier 'MeshNamespace'
    class ReferenceElement : public IReferenceElement 
  {
  private:
  vector<Polygon> _referenceElementPolygons;   //(**)
  friend class MeshNameSpace::Mesh; //ReferenceElement.hpp:45:20: error: use of undeclared identifier 'MeshNameSpace'
  };
}

//file Mesh.hpp

#include "Mesh.hpp"
    using namespace ReferenceElementNamespace;
    namespace MeshNamespace {
          class Mesh : public IMesh{
                  someFunction(ReferenceElement& referenceElement)
                  {
                    ReferenceElement ref;
                    Polygon &polygon = ref._referenceElementPolygons[0];  //Mesh.cpp:216:32: error: '_referenceElementPolygons' is a private member of 'ReferenceElementNamespace::ReferenceElement'
    ReferenceElement.hpp:34:23: note: declared private here   // in line (**)
                  }
         };
    }

Edit: By the way, I realized that forward-declaring class Mesh; instead of class MeshNamespace::Mesh; gets accepted because it like declaring a new class in namespace ReferenceElementNamespace, but then I am getting ambiguity in another file where I use MeshNamespace and ReferenceElementNamespace with using. Still this doesn't solve anything

Upvotes: 1

Views: 1037

Answers (1)

Scheff&#39;s Cat
Scheff&#39;s Cat

Reputation: 20141

What I know:

  1. Forward declarations in (other) namespaces are supported.
  2. Forward declarations of nested classes are not supported.

OP wrote:

class MeshNamespace::Mesh;

class OtherClass {
friend class MeshNamespace::Mesh;
};

to forward declare a class Mesh in a namespace MeshNamespace.

It could be as well a class MeshNamespace { class Mesh { } } but this is a forward declaration of a nested class (which is not supported).

I'm not sure how to distinguish it, and it seems the compiler cannot as well. However, the fix is simple:

namespace MeshNamespace {
class Mesh;
}

class OtherClass {
friend class MeshNamespace::Mesh;
};

Demo on coliru


Note:

Since C++17, nested namespace definitions are allowed:
namespace X::Y { } is considered equal to namespace X { namespace Y { } }.

This seems to be true for class definitions as well. So, adding a definition

class MeshNamespace::Mesh { };

after the namespace MeshNamespace has been defined once is fine. (However, this is an error as well before the namespace MeshNamespace has been defined at least once.)

Demo on coliru

Upvotes: 2

Related Questions