Hello,
I use the GLM math library in my opengl applications.
When I store an Object into a stl::map that has members
of types from GLM like glm::vec3 then I get an error for
an unresolved external symbol.
Please have a look at this piece of code
class CFoo
{
private:
glm::vec3 abc;
public:
....
}
...
map<string, CFoo*> FooMap;
map<string, CFoo*>::iterator It = FooMap.find("a_Foo");
if(It != FooMap.end()) <---- this line causes the error
{
...
}
The if statement causes the unresolved external symbol error.
unresolved external symbol “bool __cdecl glm::gtx::comparison::operator!=…”
But when I use a const_iterator the error does not appear.
Did anyone has the same problem with it ?
In some cases I cant use a const iterator, e.g. removing objects from a map.
any ideas ?
if(It != FooMap.end()) <---- this line causes the error
Nope, sorry; I don’t buy it.
Iterator comparison, even std::map iterators, does not do deep comparisons. It does not compare the objects contained in the container. And even if it could (and it doesn’t), it wouldn’t be able to do deep comparisons with the .second values (Foo*) because it’s a Foo* and not a Foo object. It would compare the pointers. The only way for that to be a deep comparison is if you overloaded the comparison operators for Foo*/Foo* comparisons.
Which again, even if you did, doesn’t get around the fact that iterator comparison doesn’t compare the contents of the iterators.
On the other hand, GLM is a header-only library so it is pretty unsure that it produces a link error, unless something gone really wrong in how you use it.
I made a test project with visual studio 2005 and I can reproduce the error.
here is the code
// OglForum.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <map>
#include <utility>
#include <string>
#include "glm\glm.hpp"
#include "glm\ext.hpp"
using namespace std;
class Foo
{
protected:
glm::vec3 a;
glm::vec3 b;
glm::vec3 c;
public:
Foo(){}
};
int _tmain(int argc, _TCHAR* argv[])
{
map<string, Foo*> foomap;
foomap.insert(pair<string, Foo*>("A", new Foo));
foomap.insert(pair<string, Foo*>("B", new Foo));
foomap.insert(pair<string, Foo*>("C", new Foo));
map<string, Foo*>::iterator it = foomap.find("A");
if(it != foomap.end())
{
delete it->second;
foomap.erase(it);
}
return 0;
}
And again, the if(it != foomap.end()) is the reason for the error. Further more with the following code I also get this error. The only difference is, that I only included the GLM headers. This seems to be sufficient to cause this error. I dont know why.
// OglForum.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <map>
#include <utility>
#include <string>
#include "glm\glm.hpp"
#include "glm\ext.hpp"
using namespace std;
class Foo
{
protected:
//glm::vec3 a;
//glm::vec3 b;
//glm::vec3 c;
public:
Foo(){}
};
int _tmain(int argc, _TCHAR* argv[])
{
map<string, Foo*> foomap;
foomap.insert(pair<string, Foo*>("A", new Foo));
foomap.insert(pair<string, Foo*>("B", new Foo));
foomap.insert(pair<string, Foo*>("C", new Foo));
map<string, Foo*>::iterator it = foomap.find("A");
if(it != foomap.end())
{
delete it->second;
foomap.erase(it);
}
return 0;
}
If I dont include the glm headers everything is ok.
Any ideas ? Did I miss some important work to do when using
stl::map ?
My advice would be to include glm/glm.hpp and only the extra features you need instead of glm/ext.hpp which is actually recommended for any GLM users anyway.
That doesn’t fix the problem but it will work for you as long as you don’t include “glm/gtx/comparison.hpp” which is a problem somehow for you.
And in the inline file you define the operator for all your
types (vec2, vec3 etc).
If I copy the the part for the != operator from the inline file (comparison.inl) to the comparison.hpp and comment out the corresponding code in the inline file then it works.
I dont know why but it is working that way. I had this problem
on two different machinese and both with visual studio 2005 (SP1) and visual 2010 installed.