bare naked pointer
bare naked pointer

Reputation: 33

Passing anonymous classes to private member functions

Is it possible to use a class defined in an anonymous namespace as a parameter in a private member function? I haven’t found a way to forward declare AnonymousHelperClass in the header.

// C.h
class C
{
  // ...
private:
  void Boing(AnonymousHelperClass &helper);
};

.

// C.cpp
namespace
{
  class AnonymousHelperClass
  {
    // . . . 
  };
}

C::Boing(AnonymousHelperClass &helper)
{
  // ...
}

Upvotes: 3

Views: 339

Answers (2)

In silico
In silico

Reputation: 52207

No, because unnamed namespaces (that's what they're actually called) are defined like this in the C++ standard:

7.3.1.1 Unnamed namespaces [namespace.unnamed]

1. An unnamed-namespace-definition behaves as if it were replaced by

    namespace unique { /* empty body */ }
    using namespace unique;
    namespace unique { namespace-body }

where all occurrences of unique in a translation unit are replaced by the same identifier and this identifier differs from all other identifiers in the entire program.

So with your class it's equivalent to:

namespace SomeUniqueNameGeneratedByTheCompiler {}
using namespace SomeUniqueNameGeneratedByTheCompiler;
namespace SomeUniqueNameGeneratedByTheCompiler
{    
    class AnonymousHelperClass    
    {    
        // . . .     
    };    
}

So the full qualification of the AnonymousHelperClass class is ::SomeUniqueNameGeneratedByTheCompiler::AnonymousHelperClass, not ::AnonymousHelperClass. So even if you did this:

class AnonymousHelperClass; // Forward declaration

class C     
{     
  // ...     
private:     
  void Boing(AnonymousHelperClass &helper);     
};  

That forward declaration refers to a different AnonymousHelperClass. You could put the forward declaration in the SomeUniqueNameGeneratedByTheCompiler namespace, but since only the compiler knows this name, it can't be done.

Upvotes: 2

James McNellis
James McNellis

Reputation: 355307

No, because there is no way to name the type in the header file.

However, you could turn the private member function into a template:

// C.h
class C
{
public:

    void Foo();

private:
    template <typename TAnonymousHelper>
    void Boing(TAnonymousHelper&);
};

Then define it in the source file and use it with the AnonymousHelperClass:

// C.cpp
#include "C.h"

namespace
{
    class AnonymousHelperClass { };
}

template <typename TAnonymousHelper>
void C::Boing(TAnonymousHelper& x) { }

void C::Foo()
{
    AnonymousHelperClass x;
    Boing(x);
}

Though really, it's probably easier just to rework your logic such that the private member function can be a namespace-scope function in the .cpp file.

Upvotes: 4

Related Questions