suszterpatt
suszterpatt

Reputation: 8273

Is there a way to typedef this?

Simplified version of the code:

Foo.h:

class Foo {
    private:
        class Bar {
            // ...
        };
        typedef std::map<int, Bar> mapType;
        mapType _map;
    public:
        void method(mapType::iterator it);
};

Foo.cpp:

void Foo::method(mapType::iterator it) {
    // ...
    notMethod(it);
}

void notMethod(mapType::iterator it) {
    // ...
}

Unsurprisingly, I get the error 'mapType' is not a class or namespace name in VS2008 at notMethod's definition. Is there any (elegant) way that I can avoid having to type out std::map<int, Bar> everywere in notMethod's definition without turning notMethod into a method?

Upvotes: 1

Views: 826

Answers (4)

Martin B
Martin B

Reputation: 24140

Use

void notMethod(Foo::mapType::iterator it) {
    // ...
}

and put the typedef in the public section of Foo's class declaration.

Edit:

If you want to avoid this, you can

  1. make notMethod a friend (as suggested by DanDan),
  2. use sbi's template solution, or
  3. make notMethod a private static member function of Foo (which generates exactly the same code as if it was a free non-member function).

Which solution is the most appropriate really depends on what notMethod does.

If notMethod uses Bar and Bar really only makes sense in the context of Foo's internal implementation, I would make notMethod a private static member function, since it's part of Foo's internals.

If notMethod was an operator that needs to take a non-Foo as its first argument (meaning that it can't be a member of Foo), and if I wanted to keep Bar private, I would make the operator a friend.

If notMethod implements a generic operation on iterators, I would make it a template function.

If Bar is a class that might be of interest to Foo's clients, I would make Bar and the typedef public and use the solution I suggested originally.

Upvotes: 20

sbi
sbi

Reputation: 224069

Martin B has provided you with an answer. Here's an alternative:

Your notMethod() looks like some implementation detail to me, that's likely defined in the cpp file's unnamed namespace. What I usually do in this case is to make notMethod() a template:

template< typename It >
void notMethod(It it) {
    // ...
}

Besides avoiding to make the typedef public or making the function a friend, this has the added benefit that, should the function provide a useful algorithm, you can invoke it with other iterators, too.

Upvotes: 3

Mizipzor
Mizipzor

Reputation: 52341

Building upon Martin B's answer:

The reason notMethod doesnt know the type mapType is because it is inside the class Foo, you can think of classes as namespaces in this case if you want.

Either way, you must change the code to:

void notMethod(Foo::mapType::iterator it) {}

If you agree with Martin B, you must move the typedef to the public section of the class. If you agree with DanDan you must Friend the function.

Myself? I would put the typedef outside the class, and put both the class and the typedef into a namespace.

Upvotes: 4

DanDan
DanDan

Reputation: 10562

Friends.

Add

friend void notMethod(mapType::iterator it);

to your Foo class and you can keep your inner classes and functions private.

Upvotes: 4

Related Questions