0

Why am I unable to define a function inside a namespace in a .cpp file (not main.cpp)?

For example, say I want to split my code up into 2 different files, main.cpp, and then lib.cpp (with an associated lib.h file).

The following setup throws a linker error: lib.h:

#ifndef LIB_H_
#define LIB_H_
namespace a{
void foo();
}
#endif

lib.cpp:

#include "lib.h"
using namespace a;
void foo(){
std::cout<<"Hello World!"<<std::endl;
}

main.cpp:

#include "lib.h"
int main(){
a::foo();
return 0;
}

Almost any other variation I can think of works however.

  • Defining the function in the lib.h file instead of lib.cpp works
  • Removing the namespace works
  • Keeping the namespace and instead having foo as a public method in a class which I instantiate in the main function, and then call, works

It seems to me like this might be a convention thing? To encourage people to either use classes or to define the function fully in a .h file? The linker error I'm getting is "undefined symbols(a::foo()) for architecture..."

Why does this happen? I'm on a mac using CLion.

  • You've declared a function `a::foo`, but you define a global namespace function `::foo`. Your declaration should be within a `namespace { }` block, or declared as `void a::foo() { }`; a `using namespace` declaration is insufficient. – 1201ProgramAlarm Jul 25 '20 at 21:44

2 Answers2

1

using namespace a; is not a way to define a function inside a namespace.

The syntax is the same as with the declaration: namespace a { ... }

#include "lib.h"
namespace a {
    void foo(){
        std::cout<<"Hello World!"<<std::endl;
    }
}

For more details refer to: Namespaces.

rustyx
  • 80,671
  • 25
  • 200
  • 267
0

You have to add

target_link_libraries(<name of your executable> <name of your library>)

to link the library symbols and functions to your executable.

And you are defining the function in global namespace.

Define your function like this in lib.cpp

void a::foo() {
    ...
}

See comments in the code below

lib.h

#ifndef LIB_H_ 
#define LIB_H_ 
namespace a{ 
    void foo(); // declaring a::foo()
} 
#endif

lib.cpp

#include "lib.h" 
using namespace a; 
void foo(){ // defining ::foo() and thats why calling foo() without namespace a works
    std::cout<<"Hello World!"<<std::endl; 
}
MatzZze
  • 391
  • 1
  • 7
  • Thanks! But my my cmake already was using the add_library() and target_link_libraries(), and they seem to be working as well, since I can declare classes in the .h file and define them in my .cpp file, even if they are part of a namespace – davedawave Jul 25 '20 at 22:49