C++ std::map look for values but not keys - find

I have a std::map which maps a structure to a string:
struct st
{
std::string name;
int age;
}
std::map<st, std::string> m_SoundStructList;
Now I want to look in the map based on a string which is the name and get the structure.
std::string lName="Kate"
auto iter = m_SoundStructList.find(lName);
st lStruct=it->fisrt;
Now it is only possible for me to apply find on structure but the strings.
Any help would be appreciated.

You probably have to iterate through the map and use the matching element manually.
For C++11 it would be
for(const auto& p : m_SoundStructList) {
if (p.second.name == "Kate") {
// Do something
}
}

Related

How do I implement hash functions for arbitrary record types in ReScript?

I'm exploring ReScript for the first time. I want to build a hashmap using a record type as my key type, and I'm looking for guidance on implementing the hash function.
Here's my ReScript code:
type pointer = { id: string, table: string, spaceId: option<string> }
module PointerHash = Belt.Id.MakeHashable({
type t = pointer
let hash = a => 0 /* How do I implement this? */
let eq = (a, b) =>
a.id == b.id &&
a.table == b.table &&
switch (a.spaceId, b.spaceId) {
| (Some(aid), Some(bid)) => aid == bid
| _ => false
}
})
I looked through the docs and searched online but didn't find any guidance about how to implement the hash function.
In other programming languages like eg Java that expect you to implement hashCode(), there are ubiquitous tools to support composing existing hash functions.
class Pointer {
public final id: String
public final table: String
public final #Nullable spaceId: String
/* omitting constructor, etc */
#Override
public int hashCode() {
// Standard helper for implementing hashCode()
return Objects.hash(this.id, this.table, this.spaceId);
}
}
I looked at the implementation of Belt.HashMapString to see if there were any hints, and it looks like HashMapString uses caml_hash_mix_string:
external caml_hash_mix_string : seed -> string -> seed = "caml_hash_mix_string"
external final_mix : seed -> seed = "caml_hash_final_mix"
let hash (s : key) =
final_mix (caml_hash_mix_string 0 s )
What is the most idiomatic way to access and compose "hash mix" functions? Are these available with a nice interface from ReScript?
There's a built-in polymorphic hash function in the Hashtbl module:
let hash: 'a => int
This comes from the OCaml standard library which ReScript inherits. You can find the documentation there: https://docs.ocaml.pro/html/LIBRARY.stdlib#ocaml-base-compiler.4.10.0/Stdlib/Hashtbl/index.html#val-hash

Invalid initialization of reference type 'Class&' from expression of type 'Class'

Ok guys , so I have a list of objects and I want to sort my list by a boolean function I created .
Function ->
bool funct(Student &s1,Student &s2)
{
return s1.calculMedie()<s2.calculMedie();
}
I got this list:
list<Student*> list;
list.push_back(sx[0]);
list.push_back(sx[1]);
list.push_back(sx[2]);
sx is comming from this declaration-> Student **sx=new Student*[3];
I created 3 objects of the type class Student.
I want to sort them by 'calculMedie()' which is a function that returns their average grade.
double Student::calculMedie()
{
int nr=0;
double s=0;
for(auto i : note)
{
nr++;
s=s+i;
}
return s/nr;}
^ thats how it looks.
And when I tried to do a list.sort(list.begin(),list.end(),funct) it gets me this error : " Invalid initialization of reference type 'Class&' from expression of type 'Class'"
It looks like you mixed std::sort algorithm with list<T>::sort method. List can be sorted only by using its sort method.
There are two overloads of list::sort:
void sort();
template< class Compare >
void sort( Compare comp ); // [2]
if you want to sort by comparator, write as follows:
list<Student*> list;
list.sort (funct);
because list stores pointers to Student, you need to modify signature of funct function, it must takes pointers not references:
bool funct(Student* s1,Student* s2)
{
return s1->calculMedie()<s2->calculMedie();
}
good practice is to pass s1,s2 as pointers to const object, when you change s1,s2 to be const Student* s1, const Student* s2 you need also to make calculMedie as const member function.

NTriplesParser extract textual value from string

I am using dotnetrdf and trying to parse some triples with NTriplesParser. I have my own handler RobHandler in which I process each triple in turn.
public class RobHandler : BaseRdfHandler
{
protected override bool HandleTripleInternal(Triple t)
{
string predicateUrl = ((BaseUriNode)(t.Predicate)).Uri.AbsoluteUri;
string value = t.Object.ToString();
}
}
This works fine but I want to get the object minus the language. My objects look like "Lincoln"#en. I could obviously write some code to remove the #en bit, but I'd rather use some library code rather than my own that hard-coded strings like #en. To do this I think I need to create a LiteralNode but there doesn't seem to be a way to get from a string which is what I have (my variable value) to a LiteralNode.
How can I extract just the textual value from an object string?
Actually I think I have the answer myself:
if (t.Object.NodeType == NodeType.Literal)
{
var node = (ILiteralNode)t.Object;
}

Get Class from string -- Call function by string name

OK, what I'm trying to do is fairy complicated, but I'll try to explain.
Let's say we want (at compile-time) all derivedMembers of class someClass. Then we'd simply do :
const string[] methods = [__traits(derivedMembers,someClass)];
Now, how could we get someClass from "someClass"? (yep, its string representation).
Let me explain a bit more what I'm trying to do :
I want to create an "intermediate" function which takes a function name as an argument (along with a params array) and calls the appropriate function from a list of available static methods in a specific (predefined) set of classes. Like execute("someFunc",["one","two","three"]);.
Here's the full (test) code :
class Math {
static string noArgs(string[] s) { writeln(s); return ""; }
static string withOneArg(string[] s) { writeln(s); return ""; }
static string withTwoArgs(string[] s) { writeln(s); return ""; }
}
string cases()
{
string ret = "";
const string[] methods = [__traits(derivedMembers,Math)];
foreach (string s; methods)
{
ret ~= "case \"" ~ s ~ "\": return Math."~s~"(params);";
}
return ret;
}
string execute(string what, string[] params)
{
switch (what)
{
mixin(cases());
default: break;
}
return "";
}
The trouble with the above code is that it only looks for methods in Math. How could I change it, in an elegant D-friendly way, so that it'll go through an array of classes like [Math,String,SomethingElse] -- it doesn't have to be variable (we need it at compile-time anyway)?
UPDATE:
Tried something along the lines of :
const string[] methods = [__traits(derivedMembers,mixin("Math")];
but it complains that Cannot interpret Math at compile time.
UPDATE 2:
Also, tried using Object.factory("Math") but it's still not working. (Perhaps I'm just creating an instance of the Math class?)
Let me rewrite this to show you some cool tricks:
import std.stdio;
class Math {
static string noArgs(string[] s) { writeln(s); return ""; }
static string withOneArg(string[] s) { writeln(s); return ""; }
static string withTwoArgs(string[] s) { writeln(s); return ""; }
}
class String {
static string oneArg(string[] s) { return null; }
}
string execute(string what, string[] params) {
import std.string;
auto parts = what.split(".");
auto className = parts[0];
auto methodName = parts[1];
import std.typetuple;
switch(className) {
default: assert(0, "unknown class");
foreach(possibleClass; TypeTuple!(Math, String)) {
case possibleClass.stringof:
switch(methodName) {
default: assert(0, "unknown method");
foreach(memberName; __traits(derivedMembers, possibleClass)) {
case memberName:
return __traits(getMember, possibleClass, memberName)(params);
break;
}
}
break;
}
}
assert(0);
}
void main() {
execute("Math.withOneArg", ["cool"]);
execute("String.oneArg", ["cool"]);
}
Notice that there are no mixin expressions used at all. Instead of getting an instance of the class from a string, I just made a TypeTuple of all the classes I wanted to use. This is preferable to mixin because then it is less likely to find name classes when used in different scopes; if possibleClasses were a compile-time parameter to execute from a different module, the list of classes would still work, whereas the list of strings would see undefined identifier errors because the library module doesn't import your user module.
Another mixin I removed was the one to generate the cases. This looks insane, but is allowed in D: if you have a compile-time foreach (that is, a foreach over a built-in tuple of some sort, e.g. TypeTuple, template argument lists, the results of __traits...) you can actually put case statements inside them!
So, all you have to do is write a regular switch statement on the run time variable you want to compare against, put the foreach inside it looping over the compile-time stuff you're searching for, case that_loop_var: and boom, you're in business.
Similarly, I used __traits(getMember) rather than a mixin string to call the method. This solution will help avoid name clashes and IMO is cleaner code. It can also potentially handle overloads, if wanted (with __traits(getOverloads) instead of __traits(getMember), you can loop over each one then and match the parameter types).
Finally, nesting switches inside other case statements is allowed. If you need to break out of an outer loop or switch and don't want ambiguity, you can label loops and switches and use break label_name_here; to specify which one you want to break from. Ditto for continue with nested loops.
BTW you could also automatically generate the wrapper functions that convert string[] to other types of arguments if you dove into the std.traits stuff. I wish my book was out already, I wrote about this at some length in there and don't feel like writing it all right now but if you look at std.traits.ParameterTypeTuple and ReturnType in the same module that will get you started if you wanna try it.

Finding a on object in a vector by one of its values

The problem I encountered and am unable to solve goes something like this. I have two classes:
class1
{
private:
int identifier;
double value;
public:
setters,getters,etc...
}
class2
{
private:
vector<class1> objects;
vector<int> some_value;
vector<double> other_value;
...
}
The problem is I need to search through the vector of objects in an object of the second class by its identifier in the class1 object(from a member function of class2). I tried something like:
int getObj(const int &ident, double &returnedValue, double &returnedOther_value)
{
int p;
p = find(objects.begin()->getIdentifier(),objects.end()->getIdentifier(),ident);
..
.. and then i was hoping to find a way to return from the found iterator values of corresponding(non-const) member variables value and other_value from both classes, but the code so far does not compile, because I'm likely doing the search all wrong. Is there a way I could do this with the find(or any other algorithm) or should I stick to my previous working realization with no algorithms?
You need to use find_if with a custom predicate. Something like:
class HasIdentifier:public unary_function<class1, bool>
{
public:
HasIdentifier(int id) : m_id(id) { }
bool operator()(const class1& c)const
{
return (c.getIdentifier() == m_id);
}
private:
int m_id;
};
// Then, to find it:
vector<class1>::iterator itElem = find_if(objects.begin(), objects.end(), HasIdentifier(ident));
I haven't tested it, so maybe it needs some tweaking.
If you have C11, I guess you can use lambdas, but I don't have it, so I haven't had the chance to learn them.
UPDATE:
I've added an example in http://ideone.com/D1DWU