why this std::bind fails? - c++

What is the fault of this bind operation with visual studio 2013 for error C3867 ?
#include <map>
#include <vector>
#include <algorithm>
#include <functional>
int main()
{
std::map<int, int> m1, m2;
std::vector<std::map<int, int> *> pM;
std::for_each(pM.begin(), pM.end(),
std::bind(std::map<int, int>::erase , 1));
}

If you want to delete each map's element (which key is 1) in the vector. Here is a sample.
#include <map>
#include <vector>
#include <algorithm>
#include <functional>
#include <iostream>
using namespace std;
using namespace std::placeholders;
int main()
{
std::map<int, int> m1 {{1,2},{2,3},{3,4}}, m2 {{2,3},{1,5},{8,9}};
std::vector<std::map<int, int> *> pM {&m1,&m2};
size_t(std::map<int,int>::*pf)(const int& key)=&std::map<int,int>::erase;//note this line.
std::for_each(pM.begin(), pM.end(),std::bind(pf,_1,1));//note this line
for(auto& ele:m1)
{
cout<<ele.first<<","<<ele.second<<endl;
}
for(auto& ele:m2)
{
cout<<ele.first<<","<<ele.second<<endl;
}
}
As chris says:
For one thing, member functions do not decay into member function
pointers. For another, std::map::erase is overloaded.
We must use & to get member function pointer,and must tell compiler which overload function you want to choice.
So write code like this:
size_t(std::map<int,int>::*pf)(const int& key)=&std::map<int,int>::erase;
And further:
std::bind(pf,_1,1)
member function need object as its implicit first parameter, _1 do this work.The last parameter 1 is int as the key pass to map erase member function.

Related

STL map composite

#include <iostream>
#include <algorithm>
#include <climits>
#include <map>
#include <unordered_map>
using namespace std;
int main()
{
std::map<int, std::unordered_map<std::pair<int, int>, int>> region;
region[0].insert(make_pair(make_pair(1, 1), 1));
return 0;
}
I am writing the above code and it don't work as expected, How can I fixed it? The error is " error C2064: term does not evaluate to a function taking 1 arguments"
There is no specialization of std::hash for std::pair, so it can't be used as a key for std::unordered_map unless you provide a custom hash function.

Why Universal Reference concept not working for map insert in case of function pointers

Can someone explain why below piece of code is not working if I don't use explicitly std::pair with map insert :
#include <iostream>
#include <string>
#include <map>
#include <memory>
typedef std::shared_ptr<int>(*CreatorFunction)();
std::shared_ptr<int> test()
{
std::shared_ptr<int> p(new int);
return p;
}
int main()
{
std::map<int, CreatorFunction> tmap;
tmap.insert(1,test); //this doesn't work
tmap.insert(std::pair<int,CreatorFunction>(1,test)); //this works
return 0;
}
My understanding is in c++14 we don't need to use std::pair as insert function definition is changed to accept universal reference as indicated below :
template <class P> pair<iterator,bool> insert (P&& val);
There is no any overload in std::map::insert that takes two arguments you should use std::make_pair. See the snippet below
#include <iostream>
#include <string>
#include <map>
#include <memory>
#include <functional> // for std::function.
// typedef std::shared_ptr<int>(*CreatorFunction)();
typedef std::function<std::shared_ptr<int>()> CreatorFunction; // The c++ way.
// Take a look at this function. std::shared_ptr<int> will automatically destroy the int* and might result in undefined.
std::shared_ptr<int> test()
{
std::shared_ptr<int> p(new int);
return p;
}
int main()
{
std::map<int, CreatorFunction> tmap;
tmap.insert(std::make_pair(1,test)); // edited this line
tmap.insert(std::pair<int,CreatorFunction>(1,test)); // this works
return 0;
}

implementing map<mpz_t, double> in c++

For some reason, I need to have a map from arbitrary huge number to double and I tried to implement it with c++98 (and I have to) and Xcode but it doesn't work:
#include <iostream>
#include <string>
#include <map>
#include <vector>
#include <set>
#include "gurobi_c++.h"
#include <sstream>
#include "boost/tuple/tuple.hpp"
#include "boost/tuple/tuple_comparison.hpp"
#include "boost/tuple/tuple_io.hpp"
#include <cmath>
#include <gmp.h>
using namespace std;
using namespace ::boost::tuples;
using namespace ::boost;
int main()
{
map<mpz_t, double>J;
mpz_t a,b,c,n;
string tempstring;
int xrange=5,yrange=5,component=5;
mpz_set_str(n,"11", 10);
J[n]=-1;
return 0;
}
The error shown is: Array initializer must be an initializer list. Could someone help me with it? Thank you:)
Here's the detail error page:
I don't know the details of mpz_t. However, it appears to be an array.
You can get around the problem by defining a class to be used as the key in your map.
I am able to create an executable using the following code with g++ 4.8.2.
#include <map>
using namespace std;
typedef int (mpz_t)[2];
struct MyKey
{
// Add a proper implementation of a constructor
// with mpz_t.
MyKey(mpz_t in) {}
// Add a proper implementation of copy constructor.
MyKey(MyKey const& copy) {}
// Add a proper implementation of assignment operator.
MyKey& operator=(MyKey const& rhs)
{
return *this;
}
bool operator<(MyKey const& rhs) const
{
// Add a proper implementation.
return false;
}
mpz_t n;
};
int main()
{
map<MyKey, double> J;
mpz_t n;
J[n] = 1.0;
return 0;
}

I can't declare a map

So in my cpp file I'm trying to declare a map as follows:
map<string, vector<myStruct>> myMap;
At the top of my file I have written using namespace std and I also have #include <string>
.
However I'm getting these weird errors:
error: ISO C++ forbids declaration of ‘map’ with no type
I don't know how to fix it. If I write #include <map> that just causes the compiler to freak out.
do you have #include <map>? rest looks valid,
however you might need to add a space if your C++ standard is not C++11:
#include <map>
#include <vector>
#include <string>
using namespace std;
map<string, vector<myStruct> > myMap;
^^^
even better not use namespace std:
#include <map>
#include <vector>
#include <string>
std::map<std::string, std::vector<myStruct> > myMap;
You need to include map header file.
#include <map>
Meanwhile, in case you are not using C++11, you need a space:
map<string, vector<myStruct> > myMap;
//^^
You should also include <map>. std::map is introduced through this header.
Furthermore, using namespace std is considered a bad practice. You should either have a using statement or use the prefix the name with std:: to denote a fully-qualified identifier:
#include <map>
#include <string>
#include <vector>
std::map<std::string, std::vector<myStruct>> myMap;
Note, the lack of a using statement ;)
#include <vector>
#include <string>
#include <map>
#include <iostream>
typedef int myStruct;
std::map<std::string, std::vector<myStruct>> myMap;
int
main()
{
std::vector<myStruct> testMe = { 1, 2, 3};
myMap["myTest"] = testMe;
std::cout << myMap.size() << std::endl;
return(0);
}

Can't assign to mapType::const_iterator? ("no operator = matches")

typedef map<string,int> mapType;
mapType::const_iterator i;
i = find_if( d.begin(), d.end(), isalnum );
at the '=' i am getting the error:
Error:no operator "=" matches these operands
I know that find_if returns an iterator once the pred resolves to true, so what is the deal?
The documentation for std::find_if
We can only guess at the error as you have only provided half the problem.
Assuming d is mapType and the correct version of isalnum
The problem is that the functor is being passed an object to mapType::value_type (which is how the map and all containers store their value). For map the value_type is actually a key/value pair actually implemented as std::pair<Key,Value>. So you need to get the second part of the object to test with isalnum().
Here I have wrapped that translation inside another functor isAlphaNumFromMap that can be used by find_if
#include <map>
#include <string>
#include <algorithm>
// Using ctype.h brings the C functions into the global namespace
// If you use cctype instead it brings them into the std namespace
// Note: They may be n both namespaces according to the new standard.
#include <ctype.h>
typedef std::map<std::string,int> mapType;
struct isAlphaNumFromMap
{
bool operator()(mapType::value_type const& v) const
{
return ::isalnum(v.second);
}
};
int main()
{
mapType::const_iterator i;
mapType d;
i = std::find_if( d.begin(), d.end(), isAlphaNumFromMap() );
}
If d is a map, then the problem is with your attempted use of isalnum.
isalnum takes a single int parameter, but the predicate called by find_if receives a map::value_type. The types are not compatible, so you need something that adapts find_if to `isalnum. Such as this:
#include <cstdlib>
#include <map>
#include <string>
#include <algorithm>
using namespace std;
typedef map<string,int> mapType;
bool is_alnum(mapType::value_type v)
{
return 0 != isalnum(v.second);
}
int main()
{
mapType::const_iterator i;
mapType d;
i = find_if( d.begin(), d.end(), is_alnum );
}