Search code examples
c++c++11eclipse-cdt

'Foo' in namespace 'bar' does not name a type for object member in header file


As a preface, I'm using eclipse c++ as an IDE. And I'm using the c++0x11 standard. (So I can use mutex's) I'm very new to C++ but have done some C before and am very familiar with Java programming. Also, I know .h is usually not a type for C++ files.

I'm trying to include a private object member of stellad::KeyHook in my class stellad::Dispatcher and I get the following errors when building:

Building file: ../src/KeyHook.cpp
Invoking: GCC C++ Compiler
g++ -std=c++0x -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/KeyHook.d" -MT"src/KeyHook.d" -o "src/KeyHook.o" "../src/KeyHook.cpp"
In file included from ../src/KeyHook.h:10:0,
                 from ../src/KeyHook.cpp:8:
../src/Dispatcher.h:23:11: error: ‘KeyHook’ in namespace ‘stellad’ does not name a type
  stellad::KeyHook keyhook;
           ^
src/subdir.mk:21: recipe for target 'src/KeyHook.o' failed
make: *** [src/KeyHook.o] Error 1

A lot of lines have been removed to reduce noise, such as unnecessary includes, prototypes and function declarations.

Dispatcher.h

/*
 * Dispatcher.h
 */

#ifndef DISPATCHER_H_
#define DISPATCHER_H_

#include "KeyHook.h"

namespace stellad {

class Dispatcher {
private:
    ..
    stellad::KeyHook keyhook;
public:
    Dispatcher();
    virtual ~Dispatcher();
    ..
};

} /* namespace stellad */

int main(int argc, const char* argv[]);
#endif /* DISPATCHER_H_ */

KeyHook.h

/*
 * KeyHook.h
 */

#ifndef KEYHOOK_H_
#define KEYHOOK_H_
#include "Dispatcher.h"

namespace stellad {

class KeyHook{
private:
    ..

public:
    KeyHook();
    virtual ~KeyHook();
    ..
};


} /* namespace stellad */

#endif /* KEYHOOK_H_ */

Solution

  • It's caused by each file including the other.

    If the first included is KeyHook.h, then before any declarations it includes Dispatcher.h. That includes KeyHook.h again but it finds that KEYHOOK_H_ is already defined and does not declare anything. Then the headers look like this:

    // #include "KeyHook.h" from KeyHook.cpp
    // #define KEYHOOK_H_
    
    // #include "Dispatcher.h" from KeyHook.h
    // #define DISPATCHER_H_
    
    // #include "KeyHook.h" from Dispatcher.h
    // KEYHOOK_H_ already declared
    // end of #include "KeyHook.h" from Dispatcher.h
    
    namespace stellad {
    
    class Dispatcher {
    private:
        ..
        stellad::KeyHook keyhook; // KeyHook not declared here
    public:
        Dispatcher();
        virtual ~Dispatcher();
        ..
    };
    
    } /* namespace stellad */
    
    int main(int argc, const char* argv[]);
    
    // end of #include "Dispatcher.h" from KeyHook.h
    
    namespace stellad {
    
    class KeyHook{
    private:
        ..
    
    public:
        KeyHook();
        virtual ~KeyHook();
        ..
    };
    
    } /* namespace stellad */
    

    To solve this, you need to break the cyclic inclusion. KeyHook does not require Dispatcher, simply remove #include "Dispatcher.h" from it.