Convert struct to bool value - c++

I am trying to convert struct with boolean value into an another variable of boolean type. I am trying using static_cast and reinterpet_cast.
int main()
{
bool c,d;
struct b {
bool b1 = false;
bool b2 = false;
};
c = reinterpret_cast<uint8_t*>(&b);
d = (static_cast<uint8_t*>(static_cast<void*>(&b)));
cout <<c <<endl;
cout <<d <<endl;
return 0;
}
The error is:
main.cpp:22:38: error: expected primary-expression before ')' token
c = reinterpret_cast<uint8_t*>(&b);
^
main.cpp:23:53: error: expected primary-expression before ')' token
d = (static_cast<uint8_t*>(static_cast<void*>(&b)));

You cannot convert an instance of a struct to a bool where the value is the Boolean or of all it's members with just a cast. You need to tell the compiler how to make the object a bool and you do that by overloading the operator bool for the class. In there you do the logic to tell if it should be considered true or false. That would look like
struct Foo
{
bool a = true;
bool b = true;
bool c = false;
operator bool() { return a || b || c; }
};
int main()
{
Foo f;
std::cout << static_cast<bool>(f);
}
ouput:
1
If you have a lot of members like you said you should consider using an array instead of separate members so you can write a loop instead. C++ doesn't have reflection yet so there is no easy way to tell it to or together all the members.

If you have control over the struct definition, this might be a good place to use bit-wise logic. If you have up to 128 boolean values, you could handle them them all within a couple 64-bit vars. To check an individual boolean, you'd use a mask to only check against the intended bit. And for the case described in the question, you could do a boolean-OR operation on the 64-bit vars. something like this:
struct b {
uint64_t boolset_a;
uint64_t boolset_b;
}
So if you had defined var_b to be of type struct b, you could do this to see if any of them were true: var_b.boolset_a || var_b.boolset_b
This should, I believe, be a more efficient methodology as it will not require 100+ boolean operations to see if any of them are true.

I'd not do a cast but I'd use a member function with an explicit name:
int main()
{
struct b {
bool b1 = false;
bool b2 = false;
bool b3 = false;
bool AtLeastOneIsTrue() { return b1 || b2 || b3; };
};
b str;
str.b2 = true;
cout << str.AtLeastOneIsTrue() << endl;
str.b2 = false;
cout << str.AtLeastOneIsTrue() << endl;
}
Output
1
0
But on the other hand if your struct has 100 different bool members, the AtLeastOneIsTrue function would be terrible. An array of bool or a vector of bool would be more appropriate then.
Sample using a vector:
#include <iostream>
#include <vector>
using namespace std;
int main()
{
struct b {
vector<bool> values;
b(int numberofbools) { values.assign(numberofbools, false); }; // constructor
bool AtLeastOneIsTrue()
{
for (bool v : values)
{
if (v)
return true;
}
return false;
};
void Set(int number, bool value)
{
values[number] = value;
}
};
b str(100); // str has 100 bool values, all false
cout << str.AtLeastOneIsTrue() << endl; // print1 0
str.Set(3, true); // set value number 3 to true
cout << str.AtLeastOneIsTrue() << endl; // prints 1
}

IMHO, your better create a member function or an operator for the struct, like shown by NathanOliver, that operates on the booleans in there. In fact, your could create at least two member functions, one that tells you whether any of the booleans is true, and other that tells you if all are true.
My approach, as this will probably need to be extendable in some sense in a normal project in the future, is to use a vector of booleans, or better a map, so that each boolean can be given a name, and then two functions (methods if they belong to a bigger class, like a configuration entity) that provide the all/any computation on those flags.
A quick and dirty example of this approach is shown below (compile with C++11 activated, for the auto loop, or modify otherwise):
#include <iostream>
#include <string>
#include <map>
using namespace std;
typedef map<string, bool> Flags;
bool allOK(Flags & fl) {
bool result = true;
for (auto & kv : fl) { result &= kv.second; }
return result;
}
bool anyOK(Flags & fl) {
bool result = false;
for (auto & kv : fl) { result |= kv.second; }
return result;
}
int main(int argc, char * arg[])
{
Flags flags;
flags["a"] = true;
flags["b"] = true;
flags["the_third_flag"] = false;
cout << "1. ALL OK: " << boolalpha << allOK(flags)
<< " - ANY OK: " << anyOK(flags) << '\n';
flags["the_third_flag"] = true;
cout << "2. ALL OK: " << boolalpha << allOK(flags)
<< " - ANY OK: " << anyOK(flags) << '\n';
flags["a"] = false;
flags["b"] = false;
flags["the_third_flag"] = false;
flags["a_last_flag"] = false;
cout << "3. ALL OK: " << boolalpha << allOK(flags)
<< " - ANY OK: " << anyOK(flags) << '\n';
return 0;
}

Related

C++ A function that can return one of two types depending on the accepted value

fun(int a) {
if (a) return a; return "empty";
}
I need a function that gets a number and depending on which number it is returns either an int variable or a string.
Please tell me how I can implement such a function.
With C++ 17 you can use variant:
std::variant<int, std::string> fun(int a) {
if (a) return a; return "empty";
}
Or use a struct with optional:
struct r {
std::optional<int> i;
std::optional<std::string> s;
};
r fun(int a) {
r out;
if (a) out.i = a; else out.s = "empty";
return out;
}
Or for prior standards use a struct with fields indicating validity.
struct r {
enum class type {i, s};
int i;
std::string s;
type t;
};
r fun(int a) {
r out;
if (a) {
out.i = a;
out.t = r::type::i;
else {
out.s = "empty";
out.t = r::type::s;
}
return out;
}
Interpret-able languages like python does not have restrictions on type of argument and type of return value. However, C++ can only accept and return values of pre-defined type.
Now, Adding to other answers, if you don't have C++17, You could try it this way:
std::pair<int, string> func(int a)
{
if(a) return std::make_pair(a , "");
return std::make_pair(0,"string");
}
In callee, you can check for non-null against both members of std::pair.
You could accomplish this flow with exceptions! If func is expecting to work with a number that is greater than 5, for example, you could do something like:
int func(int a) {
if (a > 5) { return a; }
throw std::runtime_error("Empty");
}
int main() {
try {
int x = func(3);
// Do some stuff with x...
} catch(const std::exception &e) {
std::cout << "Looks like the num is " << e.what();
}
}
So you either process the int if things went well, or, if something bad happened, you grab the string from the exception and deal with it.
You could accomplish this by splitting the two different tasks into separate functions and continue your execution from there.
#include <iostream>
using namespace std;int inputValue = 0;
int returnInt() {
std::cout << "Returning your int" << std::endl;
return inputValue;
}
string returnString() {
std::cout << "Returning your string" << std::endl;
return "Your string";
}
int main() {
std::cout << "Please type in a number" << "\t";
std::cin >> inputValue;
if (inputValue > 5) {
returnInt();
}
else {
returnString();
}
}

A function that returns a function pointer for functions of different return types

The context of this question revolves around hard typed genetic programming.
I would like to return a function pointer from a function but these functions pointers point to functions with different return types. In another stack overflow question (Function Pointers with Different Return Types C) a return type of union was suggested however I am struggling with the implementation.
I am fairly new to C++ so please forgive my ignorance if it shows.
#include <iostream>
#include <string>
float Add(float a, float b) { return a + b; }
bool IfElse(bool a) { if (a) { return true; } else { return false; }; }
union return_type
{
float(*ffptr)(float, float);
bool(*bfptr)(bool);
};
union fptr(std::string OPERATION) {
if (OPERATION == "Add") {
return_type.ffptr = Add;
} else if (OPERATION == "IfElse") {
return_type.bfptr = IfElse;
}
return return_type;
}
int main() {
std::cout << fptr("Add") << std::endl
return 0;
}
I expect (or rather would like) this to print the address of the function Add
TL;DR version: I think you may be trying to hammer a solution into fitting a problem. Consider using something like the Visitor pattern to decouple the problem so that you don't need to know the type of the data.
A union isn't a type. It's a type of types, like a class or a struct. In order to use a return_type, you have to make an object that is a return_type. That means
union fptr(std::string OPERATION) {
if (OPERATION == "Add") {
return_type.ffptr = Add;
} else if (OPERATION == "IfElse") {
return_type.bfptr = IfElse;
}
return return_type;
}
needs to look more like
return_type fptr(std::string OPERATION) {
return_type result; // make a return_type object
if (OPERATION == "Add") {
result.ffptr = Add; // set a member of the object
} else if (OPERATION == "IfElse") {
result.bfptr = IfElse;
}
return result; // return the object
}
Then you can
int main() {
std::cout << fptr("Add").ffptr(10,20) << std::endl; // call the stored function
return 0;
}
The big problem with unions is knowing what is in them. You can only safely use ffptr if ffptr was the last member set.
int main() {
std::cout << fptr("Add").bfptr(true) << std::endl;
return 0;
}
will compile, but will not behave well at all when run. What will happen is undefined, but odds are good that it won't be pretty.
You have to be absolutely certain that the function stored in the union is the correct one. If your compiler is up to date, you can use std::variant to help out here. It will at least tell you you're headed in the wrong direction by throwing an exception
#include <iostream>
#include <string>
#include <variant>
float Add(float a, float b) { return a + b; }
bool IfElse(bool a) { if (a) { return true; } else { return false; }; }
using return_type = std::variant<float (*)(float a, float b), bool (*)(bool a)>;
return_type fptr(std::string OPERATION) {
return_type result;
if (OPERATION == "Add") {
result = Add;
} else if (OPERATION == "IfElse") {
result = IfElse;
}
return result;
}
int main() {
std::cout << std::get<float (*)(float a, float b)>(fptr("Add"))(10,20) << std::endl;
try
{
std::cout << std::get<bool (*)(bool a)>(fptr("Add"))(true) << std::endl;
}
catch (const std::bad_variant_access& e)
{
std::cout << e.what() << std::endl;
}
return 0;
}
But at the end of the day it's still not all that useful. I think you may find the Visitor pattern or one of its friends more helpful.
You were close.
Be careful not to conflate the declaration of the (union) type name and the function return value. Since you want to reference pointer address, I added a void* to your union (fpaddr), so you can clearly identify that you are printing an address. Note that your fptr("Add") returned the union, and you needed to disambiguate which interpretation of the union you wanted.
#include <iostream>
#include <string>
float Add(float a, float b) { return a + b; }
bool IfElse(bool a) { if (a) { return true; } else { return false; }; }
//typedef //in C you would use 'typedef'
union fp_return_t
{
float(* ffptr )(float, float);
bool(* bfptr )(bool);
void* fpaddr;
}; //fp_return_t; //in C you would give the name here
fp_return_t fptr(std::string OPERATION) {
fp_return_t fp_return;
if (OPERATION == "Add") {
std::cout << "Add:" << (void*) Add << std::endl;
fp_return.ffptr = Add;
} else if (OPERATION == "IfElse") {
std::cout << "IfElse:" << (void*) IfElse << std::endl;
fp_return.bfptr = IfElse;
}
return fp_return;
}
int main() {
std::cout << fptr("Add").fpaddr << std::endl;
return 0;
}
I'm not quite sure what the ultimate goal is but here's how you can make the above compile and print the function address (printing of a plain Add added for comparison):
#include <iostream>
#include <string>
float Add(float a, float b) { return a + b; }
bool IfElse(bool a) { return a; }
union return_type
{
float(*ffptr)(float, float);
bool(*bfptr)(bool);
};
union return_type fptr(std::string OPERATION) {
union return_type r;
if (OPERATION == "Add") {
r.ffptr = Add;
} else if (OPERATION == "IfElse") {
r.bfptr = IfElse;
}
return r;
}
int main()
{
/*the void*-cast is technically nonportable but it's hard to
print fn-pointers portably*/
std::cout << reinterpret_cast<void*>(Add) << '\n';
/*you should know which union member is active: */
std::cout << reinterpret_cast<void*>(fptr("Add").ffptr) << '\n';
/*^should be the same address*/
return 0;
}

Changing a value of an element in an object that is stored in a vector in another object through an external function in C++

So made a class called ‘Item’, and the object of that class will have a 100% condition at the start, the Player stores items (with name “apple” in this case) whenever I tell him to. In the degradeT function I want to pass the whole vector containing the items that the player has picked up by far and then change the condition of each Item in that vector by -1 through the chCond function.
first error:
initial value of reference to non-const must be an lvalue
second error:
'void degradeT(std::vector<Item,std::allocator<_Ty>> &)': cannot convert argument 1 from 'std::vector<Item,std::allocator<_Ty>>' to 'std::vector<Item,std::allocator<_Ty>> &'
#include "pch.h"
#include <iostream>
#include <string>
#include <vector>
using std::cout; using std::cin; using std::endl;
using std::string; using std::vector; using std::to_string;
class Item {
private:
string name; // Item name
float condition; // Item condition
bool consumable; // Is the item consumable
public:
Item() {}
Item(string a, float b, bool c) { name = a; condition = b; consumable = c; }
Item(string a, bool c) { name = a; condition = 100.f; consumable = c; }
string getName() {
return name;
}
float getCond() {
return condition;
}
bool isCons() {
return consumable;
}
void chCond(float a) { // Change Item condition
condition += a;
}
};
//-----------------------
class Player {
private:
vector<Item> plItems; // Item container
public:
Player() {}
void pickUpItem(Item a) { // Adding Items to inventory
plItems.push_back(a);
cout << a.getName() << " added to inventory!\n";
}
void checkItemConds() { // Checking condition of all items
for (unsigned int a = 0, siz = plItems.size(); a < siz; a++) {
cout << plItems[a].getName() << "'s condition is: " << plItems[a].getCond() << "%\n";
}
}
Item returnItem(unsigned int a) { // Return a specific Item
return plItems[a];
}
int getCurInvOcc() { // Get cuurent inventory occupation
return plItems.size();
}
vector<Item> getPlItems() { // Return the vector (Item container)
return plItems;
}
};
//-------------------------
void degradeT(vector<Item>& Itemss); // Degrade item after some time
//-------------------------
int main()
{
Player me; // me
string inp; // input
int num = 1; // apple 1, apple 2, apple 3...
while (inp != "exit") {
cin >> inp;
if (inp == "addApple") {
Item apple(("apple " + to_string(num)), true);
me.pickUpItem(apple);
num++;
}
if (inp == "checkItemConds") {
me.checkItemConds();
}
if (inp == "timeTick") {
// This doesn't have anything to do with time I just want to test the function manually
degradeT(me.getPlItems());
}
}
system("PAUSE");
return 0;
}
void degradeT(vector<Item> &Itemss) {
for (unsigned int a = 0, siz = Itemss.size(); a < siz; a++) {
Itemss[a].chCond(-1);
cout << Itemss[a].getName() << endl;
}
}
I'm not sure what your question is, but your error is related to the function void degradeT(vector<Item> & Itemss).
This functions expects a reference but you are passing an r-value. You can either return a reference with getPlItems() or pass an l-value to degradeT.

Is this code legal in ISO C++?

So I'm trying to implement function parameters which can be uninitialized. Here is the code which I have written. My question is if it's legal by the ISO C++ standard (version 14 if possible).
#include <iostream>
#include <typeinfo>
using namespace std;
template<typename type>
struct nzeroinittmpliteral
{
nzeroinittmpliteral() { }
nzeroinittmpliteral(type arg) { d = arg; }
//nzeroinittmpliteral(const nzeroinittmpliteral &) = delete;
operator type () & { return d; }
operator type () && { return d; }
type d;
} ;
void func(bool bIsPointerValid, nzeroinittmpliteral<int *> pVar = {})
{
if(bIsPointerValid)
{
cout << *pVar << endl;
}
else
{
pVar = new int;
*pVar = 8;
cout << *pVar << endl;
delete pVar;
}
}
int main()
{
func(true, { (int *)&(const int &)int{9} } );
func(false);
}
If you want to pass a parameter that may be uninitialized, simply don't pass it, use overloading. Look:
void func(int value)
{
cout << value << endl;
}
void func()
{
// no 'value' was initialized here :)
func(8);
}
Or simply give a default value to the parameter if you will provide one anyway in your body:
void func(int value = 8)
{
cout << value << endl;
}
Besides that, you can take a look at boost::optional:
void func(boost::optional<int> optvalue = boost::none) {
if (optvalue) {
cout << *optvalue << endl;
} else {
// nothing passed
cout << "foo" << endl;
}
}
Directly answering your question: your code is valid.
func(true, { (int *)&(const int &)int{9} } );
By casting the temporary to a const reference, you extend its lifetime to the lifetime of the reference itself, which ends after func returns. But this is too redundant, you could simply have written:
void func(int* value) { if (value) {...} }
func(&(const int &)9);
func(nullptr);
The actual parameter being passed is your nzeroinittmpliteral and it is initialized by calling one of the constructors, always. The default constructor doesn't initialize the d member, but this is no big improvement as it is just a pointer. Using nullptr is better and removes the need for the bool parameter.

hash_multimap find not working the way it should

I've been trying to use a hash_multimap for sometime now, but the find method keeps giving me a iterator to the end of the container even though I know it found a matching key. What has me confused is that I've used the same code before for a different project with it working perfectly but now its playing up. The reason I know its finding something is because I've put a few cout in the hash function and hash compare, which is telling me that a key is found and that it matches what I gave the hash_multimap::find meathod, yet still it gives me an iterator.
first the header file
//
// HashGrid.h
// Planetarium
//
// Created by Taura J Greig on 24/08/12.
// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//
#ifndef _HASHGRID_
#define _HASHGRID_
#include <iostream>
#include <hash_map>
#include <deque>
#include "..//hashKey.h"
struct myTraits
{
static const size_t bucket_size = 4;
static const size_t min_buckets = 8;
myTraits() { };
myHash hashfunction;
myEqualTo equal_to;
size_t operator() (const hashKey& key) const
{
size_t hashval = 0;
hashval = ((key.y * globalGridWidth) + key.x);
cout << "x : " << key.x << " y : " << key.y << endl;
cout << "hashVal : " << hashval << endl;
return hashval;
}
bool operator() (const hashKey& key1, const hashKey& key2) const
{
bool test = (key1.x == key2.x && key1.y == key2.y);
cout << "equal_to = " << test << endl;
return test;
}
};
using namespace std;
//using namespace stdext;
using namespace stdext;
template <class T>
class HashGrid
{
public:
typedef deque<T *> localObjects;
typedef pair<hashKey, T *> addingPair;
typedef hash_multimap <hashKey, T *, myTraits> hashmMap;
typedef typename hash_multimap <hashKey, T *, myTraits> :: iterator hashmMapItor;
typedef pair<hashmMapItor, hashmMapItor> valueRange;
private:
hashKey keyOffsets[9];
int gridSize;
hash_multimap<hashKey, T*, myTraits> theMap;
inline bool exists(hashKey & theKey);
inline bool exists(hashKey & theKey, hashmMapItor & it);
public:
HashGrid();
void setup(int gridSize);
void update();
void draw(); // this is used for viusal debug,
void resize();
void addObject(T * object);
void getLocalObjects(float & x, float & y, int range, localObjects & p1);
};
template <class T>
inline bool HashGrid<T>::exists(hashKey & theKey)
{
hashmMapItor it;
it = theMap.find(theKey);
if (it == theMap.end())
{
return false;
}
else
{
return true;
}
}
template <class T>
inline bool HashGrid<T>::exists(hashKey & theKey,
hashmMapItor & it)
{
it = theMap.find(theKey);
if (it == theMap.end())
{
return false;
}
else
{
return true;
}
}
#include "HashGrid.cpp"
#endif
and the source file
//
// HashGrid.cpp
// Planetarium
//
// Created by Taura J Greig on 26/08/12.
// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//
#ifndef _HASHGRID_SOURCE_
#define _HASHGRID_SOURCE_
#include "HashGrid.h"
#include "ofMain.h"
template<class T>
void HashGrid<T>::update()
{
theMap.clear();
}
template <class T>
void HashGrid<T>::addObject(T *obj)
{
hashKey tempKey;
tempKey.x = int(obj -> getPos().x) / gridSize;
tempKey.y = int(obj -> getPos().y) / gridSize;
cout << "tempKey.x : " << tempKey.x << endl;
cout << "tempKey.y : " << tempKey.y << endl;
theMap.insert(addingPair(tempKey, obj));
}
template <class T>
void HashGrid<T>::getLocalObjects(float & x, float & y, int range, localObjects & p1)
{
cout << "you are gettin local objects" << endl;
int gridX = (int(x) / gridSize);
int gridY = (int(y) / gridSize);
cout << "player x : " << x << endl;
cout << "player y : " << y << endl;
cout << "girdX " << gridX << endl;
cout << "girdY " << gridY << endl;
for (int i = 0; i < 9; i++)
{
hashKey tempkey;
tempkey.x = gridX;
tempkey.y = gridY;
tempkey += keyOffsets[i];
cout << i << " tempKey : " << tempkey.x << " " << tempkey.y << endl;
cout << "exists " << exists(tempkey) << " ";
//this is where the problem lies, the exists function will always return
//false even when the key is found
if (exists(tempkey))
{
cout << "found" << endl;
hashmMapItor it;
valueRange elements;
elements = theMap.equal_range(tempkey);
for (it = elements.first; it != elements.second; it++)
{
p1.push_back(it->second);
}
}
else
{
cout << "not found" << endl;
}
}
}
#endif
Note that I've cut a lot of methods out of the block above to save space because they are unrelated to the problem at hand. However I've left their declarations in the header file. Also I am aware that there a few things that I'm doing with templates that are ugly. Just deal with it for now.
Now I'll go into detail about whats happening in the code and where the problem lies. In the getlocalobjects method, the method "exists(key)" is called to determine if the hash_multimap has an element with the key provided. I know that it does find something because as I mentioned above because I put cout in the equal_to function to tell me when its used an what its result are.
Consistently its telling me yes (via equal_to debug) it found something but the exist method will still return false. This leading me to believe that there may be a bug in hash_multimap::find since it means that even if it finds something its gives me an iterator to hash_multimap::end
So my question is am I doing horribly wrong regarding the use of the multimap? does my traits struct not have something required for the multimap to work correctly
EDIT and the implementation for the hashKey that i forgot it include
header
#ifndef _HASHKEY_
#define _HASHKEY_
#include <iostream>
using namespace std;
static int globalGridSize = 1;
static int globalGridWidth = 1;
static int globalGridHeight = 1;
struct hashKey
{
public:
int x;
int y;
hashKey();
hashKey(int x, int y);
void set(int x, int y);
void set(hashKey & key);
void printKey()
{
cout << x << " " << y << endl;
}
bool operator < (const hashKey & key1) const;
bool operator == (const hashKey & key1) const;
hashKey& operator += (hashKey & key1);
};
#endif
and source
#ifndef _HASHKEY_SOURCE_
#define _HASHKEY_SOURCE_
#include "hashKey.h"
hashKey::hashKey()
{
x = 0;
y = 0;
}
hashKey::hashKey(int x, int y)
{
hashKey::x = x;
hashKey::y = y;
}
void hashKey::set(int x, int y)
{
hashKey::x = x;
hashKey::y = y;
}
void hashKey::set(hashKey &key)
{
x = key.x;
y = key.y;
cout << "set: x = " << x << " y = " << y << endl;
}
bool hashKey::operator<(const hashKey &key1) const
{
if ( (this->x < key1.x) && (this->y < key1.y))
{
return true;
}
return false;
}
bool hashKey::operator == (const hashKey &key1) const
{
if ((this-> x == key1.x) && (this->y == key1.y))
{
return true;
}
return false;
}
hashKey& hashKey::operator+=(hashKey &key1)
{
this->x += key1.x;
this->y += key1.y;
return *this;
}
#endif
EDIT [SOVLED] I changed the hash_multimap tp an unordered_multimap and now it works, so initial suspicion was right, that at this time the hash_multimap is bugged an its find method will always give an iterator to the the end. Note that i'm using visual studio c++ 2010, it may not be bugged on other platforms or other compilers, however it defiantly was bugged in my case
The content below is speculation as not all the relevant code is visible.
It seems that you have:
A hash which is of type size_t (as created from the first operator() of myTraits)
A key of type hashKey (which is not a hash from the hash_multimap's perspective)
You did not provide the implementation of hashKey, so my immediate question is:
Did you provide the equality operator for hashKey?
Or alternatively, did you override equal_to<haskHey>?
The potential problem (and reason for the above questions) that I see is that you defined your hashmMap as hash_multimap <hashKey, T *, myTraits> which overrides the hashing function, but it does not override the key equality (which is of type hashKey). So, I presume that the default comparator of hashKey (and not the one defined in myTraits) might be used.
Perhaps hash_multimap <hashKey, T *, myTraits, myTraits> would suffice?
Update: I just notice that VS's hash_multimap has a different signature, than the one coming from STL. Compare:
Visual Studio version
STL version
The latter has hashing function and key comparator separated. This is just asking for terrible problems once you switch compilers!