2

Consider having the following header file (c++): myclass.hpp

#ifndef MYCLASSHPP_
#define MYCLASSHPP_

namespace A {
namespace B {
namespace C {

class myclass { /* Something */ };

myclass& operator+(const myclass& mc, int i);

}}}

#endif

Consider the implemenation file: myclass.cpp

#include "myclass.hpp"
using namespace A::B::C;

myclass& operator+(const myclass& mc, int i) {
   /* Doing something */
}

Consider main file: main.cpp

#include "myclass.hpp"

int main() {
   A::B::C::myclass el = A::B::C::myclass();
   el + 1;
}

Well, the linker tells me that there is an undefined reference to A::B::C::operator+(A::B::C::myclass const&, int)

What's the problem here?

coelhudo
  • 4,710
  • 7
  • 38
  • 57
Andry
  • 16,172
  • 27
  • 138
  • 246

3 Answers3

6

Just because you're using namespace A::B::C in the implementation file doesn't mean that everything declared in there is automatically in the A::B::C namespace (otherwise, all definitions would become ambiguous if you were using more than one namespace).

myclass.cpp should look something like:

namespace A {
namespace B {
namespace C {
    myclass operator+(const myclass& mc, int i) {
        // ...
    }
}

Or (I find this cleaner):

using namespace A::B::C;

myclass A::B::C::operator+(const myclass& mc, int i) {
    // ...
}

Currently, the compiler thinks you've declared one operator+ function in the A::B::C namespace, and defined a different function that's not in a namespace at all, leading to your link error.

Cameron
  • 96,106
  • 25
  • 196
  • 225
5

A using namespace directive changes the name search order. It doesn't change where definitions are placed.

You defined operator+ in the wrong namespace.

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
1

the "using" keyword is only useful to resolve the called method. It cannot be used when defining the method. Your statement actually just defines the method in global namespace. Your definition should have been:

A::B::C::myclass A::B::C::operator+(const myclass& mc, int i) {
   /* Doing something */
}

when you are calling the method, both the following do the same thing:

using namespace A::B::C;
myclass tmp;
tmp + 1;

-OR-

A::B::C::myclass tmp;
tmp + 1;

Hope this helps...

go4sri
  • 1,490
  • 2
  • 15
  • 29
  • Yeah, actually this is also what I ended up doing... could not understand for sure if it was a namespace problem, but now it is clear! Thankyou guys – Andry Jul 06 '12 at 04:25