Search code examples
c++referencenamespacesundefinedusing

Namespaces & Undefined References


I have two sets of files one using 'namespace' and the other using 'using namespace', when I use the latter I get an undefined reference error as following:

tsunamidata.cpp:(.text+0x1a0): undefined reference to `NS_TSUNAMI::ReadTsunamiData(IntVector2D, std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > >)'
collect2: ld returned 1 exit status

This is the source file:

#include "tsunamidata.h"

using namespace std;

using namespace NS_TSUNAMI; //if I replace this with 'namespace NS_TSUNAMI' it works!!

vector< vector<double> > ReadTsunamiGrid(IntVector2D pos) {
   ifstream infile;
   infile.open("H11_V33Grid_wB_grdcor_inundated.grd");
   vector< Vector2D> range;
   infile>>range[0].x;
   infile>>range[0].y;
   infile>>range[1].x;
   infile>>range[1].y;
   IntVector2D dxdy,size;
   infile>>dxdy.i; infile>>dxdy.j;
   infile>>size.i; infile>>size.j;


   for (int j = size.j-1; j>-1; j--)
        for(int i=0; i < size.i; i++)
                infile>>tsunami_grid[j][i];

   return tsunami_grid;
}

bool Agent_drowned(IntVector2D agnt_pos) {
    ReadTsunamiData(agnt_pos, tsunami_grid );
    return true;
}

double ReadTsunamiData(IntVector2D pos, vector<vector<double> > tsunami_depth) //Function which causes the error!!
{
    return tsunami_depth[pos.j][pos.i];
}

header file:

#ifndef TSUNAMIDATA_H
#define TSUNAMIDATA_H

#include "../../Basic_headers.h"


namespace NS_TSUNAMI {


vector< vector <double> > tsunami_grid;    
bool Agent_drowned(IntVector2D agnt_pos);

vector<vector<double> > ReadTsunamiGrid(IntVector2D pos);
double ReadTsunamiData(IntVector2D pos, vector<vector<double> > tsunami_depth);
}
#endif

I don't understand why the error happens, because it only happens for that function?


Solution

  • namespace NS_TSUNAMI {
        bool Agent_drowned(IntVector2D agnt_pos);
    }
    

    This declares a function inside a namespace.

    using namespace NS_TSUNAMI;
    bool Agent_drowned(IntVector2D agnt_pos) {
        // whatever
    }
    

    This declares and defines a different function in the global namespace. The using directive makes names from the namespace available in the global namespace, but does not change the meaning of declarations.

    To define the function that was previously declared in the namespace, either put it inside the namespace:

    namespace NS_TSUNAMI {
        bool Agent_drowned(IntVector2D agnt_pos) {
            // whatever
        }
    }
    

    or qualify the name:

    bool NS_TSUNAMI::Agent_drowned(IntVector2D agnt_pos) {
        // whatever
    }