0

EDIT: Sorry to waste your time. My problem was simple, I just had the variable declared as extern in the main program. I thought something was right with my operator definition. I do see that I have other issues, like the operator= isn't right below. But, the main issue was just the missing variable.


I haven't used operator overloading in literally 20 years. So, I'm rather rusty. But, my goal is to be able to build map, hash map or unsorted map, where I can store and retrieve an internal ID integer from an IPv6 address. Which of those kinds of structures would be most suitable for my purpose, I'm open to recommendations. I figured I'd try a map first, but, if that isn't the best choice, let me know. I'm told that the requirements of my application will require up to about 100,000 IPv6 addresses. Though I'm also told it probably won't be more than 10,000 for at least a year or two. In any case, my goal is, when handed an IPv6 address, I want to quickly locate my internal ID number for that address.

So, basically, my understanding is that to be able to use the map classes, I need to provide an < operator. And, while at it, I might as well provide the remaining comparison operators. At first, I created the operators not as friend functions, with only one seen operator, and I got a compiler error, saying it was looking for an operator for with two operands. I searched the answers here, and found an answer to that question, I made it friend functions. This time, I don't get a compiler error. But, I get a linker error:

LNK2001: unresolved external symbol "class std::map,class std::allocator > > first" (?first@@3V?$map@Vipmapclass@@HU?$less@Vipmapclass@@@std@@V?$allocator@U?$pair@$$CBVipmapclass@@H@std@@@3@@std@@A) c:\Projects\mapdemo\mapdemo\mapdemo.obj mapdemo

I'm using Visual Studio 2010 in x64 mode, but, I also want the code to work with VS 2008 x64. I'm using Here is my code for the class below. Thanks for any help!

#include "targetver.h"

#include <stdio.h>
#include <stddef.h>
#include <tchar.h>
#include <conio.h>
#include <map>
#include <windows.h>
#include <In6addr.h>
#include <InAddr.h>


class ipmapclass{
public:
    union{
        in6_addr ip6addr;
        unsigned _int64  uint64[2];
    };

    inline friend bool operator==(const ipmapclass& lhs, const ipmapclass& rhs)
    {
        return ( (lhs.uint64[0] == rhs.uint64[0]) && 
                 (lhs.uint64[1] == rhs.uint64[1]) );
    }

    inline friend bool operator< (const ipmapclass& lhs, const ipmapclass& rhs)
    {
        return (  (lhs.uint64[0] <  rhs.uint64[0]) ||
                 ((lhs.uint64[0] == rhs.uint64[0]) && (lhs.uint64[1] < rhs.uint64[1])) );
    }

    inline ipmapclass operator= (const ipmapclass& rhs)
    {
        ipmapclass result;
        result.uint64[0] = rhs.uint64[0];
        result.uint64[1] = rhs.uint64[1];
        return (result);
    }

    inline friend bool operator> (const ipmapclass& lhs, const ipmapclass& rhs){return rhs < lhs;}
    inline friend bool operator<=(const ipmapclass& lhs, const ipmapclass& rhs){return !(lhs > rhs);}
    inline friend bool operator>=(const ipmapclass& lhs, const ipmapclass& rhs){return !(lhs < rhs);}
};


extern std::map<ipmapclass, int> first;
user3681853
  • 51
  • 2
  • 7
  • Funny, I just tried (MSVC 2010) and it works with no changes. I was able to build (both compile and link) with no errors. Having said that there are plenty of other errors in your class, starting with `friend` functions declared inside a class (?) and returning a **copy** of the class from an assignment operator(???) – YePhIcK Jul 05 '14 at 20:20
  • Then why just don't you try a get function? Don't do extern, in my opinion it's bad practice, but try make a function that returns the map. – Oleksandr Verhun Jul 05 '14 at 20:21
  • 1
    `unordered_map` is actually a hash map; if ordering is not required it's probably the most efficient data structure if you need key-value storage, and providing a hash function for a couple of integers is straightforward. In any case, 100000 IP is nothing to be afraid of even on the worst of current PCs even with a "regular" map (which is normally an RB tree). – Matteo Italia Jul 05 '14 at 20:24
  • possible duplicate of [What is an undefined reference/unresolved external symbol error and how do I fix it?](http://stackoverflow.com/questions/12573816/what-is-an-undefined-reference-unresolved-external-symbol-error-and-how-do-i-fix) – πάντα ῥεῖ Jul 05 '14 at 20:30
  • Okay, I'm a moron. In my main unit using the map, it was also declared as extern. Sorry for wasting your time... I will consider the other suggestions. – user3681853 Jul 05 '14 at 20:40

2 Answers2

1

I don't see anything wrong with your overloaded operators. You error has to do with the line extern std::map<ipmapclass, int> first;. That declares first as being defined in some other compilation unit. Is it?

user3553031
  • 5,990
  • 1
  • 20
  • 40
1

Other errors in your code aside the reason for the linker error is that for extern symbols you must declare that symbol in at least (and at most) one compilation unit. In your case I suspect that would be a line like that in your impclass.cpp file:

std::map<ipmapclass, int> first;

This line will tell the compiler to actually create the needed symbol and place it into impclass.obj file for later use by the linker

YePhIcK
  • 5,816
  • 2
  • 27
  • 52
  • Okay, I'm a moron. In my main unit using the map, it was also declared as extern. Sorry for wasting your time... I will consider the other suggestions. – user3681853 Jul 05 '14 at 20:40