Comments (19)
I was not able to create a hasher for cv::Point because the hash_std.cc example only works for structs.
A class is a struct in C++, they just have different default visibility of their fields/methods.
What code did you try and what errors did you get? The hasher can stay a struct, that's fine, but it is hard to diagnose without actually seeing both your complete executable code and/or the complete errors. :-)
from sparsepp.
try std::cout << map[cv::Point(1, 2)] << '\n";
from sparsepp.
just do: map[point1] = point2;
from sparsepp.
I spent some time trying to get it working with my own class using private members, and I thought I'd share how I did it if anyone else would like to do it as well.
The proper way would be to make the hasher a friend of the main class, then it could access the private fields. ^.^
If you can do it via public access though, that is always preferred.
from sparsepp.
Thank you for the help @OvermindDL1, your assistance is greatly appreciated!
from sparsepp.
@nathangeorge1, I tried to make the example as simple as possible. I assume most users of sparsepp are experienced in C++ and would know what to do when switching to a class, but I definitely could - and will -
add another example with a class. Thanks for the suggestion.
from sparsepp.
Thanks! For the user defined class, see hash_std.cc in the examples directory.
from sparsepp.
Thanks for this: https://github.com/greg7mdp/sparsepp/blob/master/examples/hash_std.cc
But instead of creating a new struct, i was interested in mapping 2 previously defined classes. Is there something I could add to the classes to have them work with sparsecpp? I'm interested in returning a class (like Person for example) rather than returning primitives within the classes.
from sparsepp.
Hum, I'm not sure I understand the question. You can create a sparse_hash_map of two classes of course. You'd have to provide a hash function for the class used as a key, like in the example I sent. What problem are you having?
from sparsepp.
I might not understand C++ enough, but in this part:
it appears that you're initializing the hash set with strings, but would this example work if you initialized it with the actual Person
?
I'm interested in doing something like spp::sparse_hash_map<cv::Point, MyData> map;
from sparsepp.
I'm interested in doing something like
spp::sparse_hash_map<cv::Point, MyData> map;
That shouldn't be a problem... go for it :-)
from sparsepp.
cool I'll try it out
from sparsepp.
I tried various things, but I could not get spp::sparse_hash_map to work with classes. Could you show me an example of how to get this to compile?
from sparsepp.
I tried various things, but I could not get spp::sparse_hash_map to work with classes. Could you show me an example of how to get this to compile?
What error did you get? Did you create a hasher for cv::Point
?
from sparsepp.
I was not able to create a hasher for cv::Point
because the hash_std.cc example only works for structs. I tried replacing "struct" with "class" but it just threw a bunch of errors, probably cause I'm not sure what I'm doing.
Could you show an example hasher for classes?
from sparsepp.
Actually I tried it again and this time I made half progress.
This code compiled and ran:
// General Includes
#include <stdlib.h>
#include <string>
#include <iostream>
#include <stdio.h>
#include <ostream>
#include <vector>
// ROS Includes
#include "ros/ros.h"
// OpenCV Includes
#include <opencv2/core.hpp>
// Project Includes
#include "utility/class_utils/Overload.hpp"
#include "utility/data_structures/sparsepp/spp.h"
// Namespaces
using namespace std;
using namespace cv;
using std::string;
namespace std
{
// inject specialization of std::hash for Person into namespace std
// ----------------------------------------------------------------
template<>
struct hash<cv::Point>
{
std::size_t operator()(cv::Point const &p) const
{
std::size_t seed = 0;
spp::hash_combine(seed, p.x);
spp::hash_combine(seed, p.y);
return seed;
}
};
}
/** @file
* @brief testbed for learning C++
*/
int main( int argc, char** argv ) {
// init
ros::init(argc, argv, "trial");
ros::NodeHandle nh;
// As we have defined a specialization of std::hash() for Person,
// we can now create sparse_hash_set or sparse_hash_map of Persons
// ----------------------------------------------------------------
spp::sparse_hash_map<cv::Point, cv::Point> map =
{
{ { 1, 2 }, {3, 4}}
};
// printing
for (auto& p: map)
std::cout << p.first << ' ' << p.second << '\n';
// accessing
// ?
return EXIT_SUCCESS;
}
But as you can see at the very end, I do not know how to access an individual mapping because the index is a cv::Point
, and it appears to only take integers and strings, as in this example on your README:
Is there a way that the index can be a class?
Also, I'd like it if I could initialize spp::sparse_hash_map<cv::Point, cv::Point> map
with actual cv::Point
s instead of inputting the raw values; is this possible too?
from sparsepp.
try std::cout << map[cv::Point(1, 2)] << '\n";
Yep this. Remember, whatever the key is, is what you pass in to get the value back out.
from sparsepp.
thanks @greg7mdp; that worked
Also, how would I attempt to initialize spp::sparse_hash_map<cv::Point, cv::Point> map
with actual cv::Points instead of inputting the raw values?
from sparsepp.
Yes that worked for publicly accessible members; thanks.
I spent some time trying to get it working with my own class using private members, and I thought I'd share how I did it if anyone else would like to do it as well.
Here is the code:
// General Includes
#include <stdlib.h>
#include <string>
#include <iostream>
#include <stdio.h>
#include <ostream>
#include <vector>
// ROS Includes
#include "ros/ros.h"
// OpenCV Includes
#include <opencv2/core.hpp>
// Project Includes
#include "utility/class_utils/Overload.hpp"
#include "utility/data_structures/sparsepp/spp.h"
#include "utility/data_types/TrimPoint.hpp"
// Namespaces
using namespace std;
using namespace cv;
using std::string;
namespace std
{
// inject specialization of std::hash for Person into namespace std
// ----------------------------------------------------------------
template<>
struct hash<TrimPoint>
{
std::size_t operator()(TrimPoint const &p) const
{
int angle = p.getAngle();
int speed = p.getSpeed();
std::size_t seed = 0;
spp::hash_combine(seed, angle);
spp::hash_combine(seed, speed);
return seed;
}
};
}
/** @file
* @brief testbed for learning C++
*/
int main( int argc, char** argv ) {
// init
ros::init(argc, argv, "trial");
ros::NodeHandle nh;
// As we have defined a specialization of std::hash() for Person,
// we can now create sparse_hash_set or sparse_hash_map of Persons
// ----------------------------------------------------------------
spp::sparse_hash_map<TrimPoint, TrimPoint> map;
TrimPoint p1(1,2,3,4,true,5);
TrimPoint p2(6,7,8,9,false,10);
map[p1] = p2;
// printing
for (auto& p: map) {
TrimPoint first = p.first;
std::cout << first << endl;
}
// accessing
cout << map[p1] << endl;
return EXIT_SUCCESS;
}
- Note the use of getters in the hasher.
- Remember to make the getters const correct
- Don't forget to overload ==; my code looks like:
- the class needs a default constructor
bool operator==(const TrimPoint &other) const {
return (this->x == other.x && this->y == other.y && this->z == other.z);
}
I would suggest, if you agree, to update your README's "Example 2 - providing a hash function for a user-defined class" with these 4 instructions for classes, as a lot of people are like me, in that they don't really know the differences between classes/structs or sets/maps, nor how to fix these build errors.
Thanks for all your help @greg7mdp. It was very helpful, and I'll now probably be using your hashmap quite often in 2 robotic startups.
Regards,
Nathan
from sparsepp.
Related Issues (20)
- Support operator[] with rvalue HOT 1
- When hashing on vector HOT 13
- Help me to serialize/deserialize sparse_hash_map<int , vector< std::string > > HOT 1
- missing return value in function spp_sptr& operator=(spp_sptr &&o) ? HOT 1
- SIGSEGV on using move-assigned-from hash set HOT 3
- Unable to create map for value type with deleted copy constructor HOT 2
- Can't insert std::tuple: spp uses deleted constructor/destructor HOT 1
- Lookup non-present keys becomes very slow. HOT 1
- Do you support C++11 stateful allocators? HOT 1
- Default allocator doesn't throw and caller doesn't check for NULL HOT 1
- SEGV after moving hash_map HOT 2
- conan package HOT 2
- sparse_hash_map<uint32_t, uint64_t> takes more memory than sparse_hash_map<uint64_t, uint64_t> HOT 1
- memcpy can happen with null "source" parameter HOT 6
- class-memaccess warning when compiling with GCC 8 or later HOT 1
- Problem when compiling on macOS catalina HOT 6
- Can sparse_hash_map support unique_ptr?
- Compiler warning on realloc call within sparsepp. HOT 1
- Error when compile: is not a special member function which can be defaulted HOT 2
- Missing return value. HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from sparsepp.