Giter Club home page Giter Club logo

Comments (19)

OvermindDL1 avatar OvermindDL1 commented on June 15, 2024 1

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.

greg7mdp avatar greg7mdp commented on June 15, 2024 1

try std::cout << map[cv::Point(1, 2)] << '\n";

from sparsepp.

greg7mdp avatar greg7mdp commented on June 15, 2024 1

just do: map[point1] = point2;

from sparsepp.

OvermindDL1 avatar OvermindDL1 commented on June 15, 2024 1

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.

greg7mdp avatar greg7mdp commented on June 15, 2024 1

Thank you for the help @OvermindDL1, your assistance is greatly appreciated!

from sparsepp.

greg7mdp avatar greg7mdp commented on June 15, 2024 1

@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.

greg7mdp avatar greg7mdp commented on June 15, 2024

Thanks! For the user defined class, see hash_std.cc in the examples directory.

from sparsepp.

 avatar commented on June 15, 2024

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.

greg7mdp avatar greg7mdp commented on June 15, 2024

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.

 avatar commented on June 15, 2024

I might not understand C++ enough, but in this part:

image
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.

greg7mdp avatar greg7mdp commented on June 15, 2024

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.

 avatar commented on June 15, 2024

cool I'll try it out

from sparsepp.

 avatar commented on June 15, 2024

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?

image

from sparsepp.

OvermindDL1 avatar OvermindDL1 commented on June 15, 2024

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.

 avatar commented on June 15, 2024

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.

 avatar commented on June 15, 2024

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;
}

with the following output:
image

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:

image

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::Points instead of inputting the raw values; is this possible too?

from sparsepp.

OvermindDL1 avatar OvermindDL1 commented on June 15, 2024

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.

 avatar commented on June 15, 2024

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.

 avatar commented on June 15, 2024

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;
}
  1. Note the use of getters in the hasher.
  2. Remember to make the getters const correct
  3. Don't forget to overload ==; my code looks like:
  4. 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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.