no matching function for call to ‘find' - c++

I have the following code:
#include <algorithm>
#include <vector>
#include <iostream>
#include <stdio.h>
using namespace std;
int main()
{
typedef vector<int> IntContainer;
typedef IntContainer::iterator IntIterator;
IntContainer vw;
IntIterator i = find(vw.begin(), vw.end(), 5);
if (i != vw.end())
{
printf("Find 5 in vector\n"); // found it
}
else
{
printf("Couldn't find 5 in vector\n"); // couldn't found it
}
return 0;
}
I try to compile it on Ubuntu with gcc 4.7.1 and get the following error:
vec_test.cpp: In function ‘int main()’:
vec_test.cpp:27:46: error: no matching function for call to ‘find(std::vector<int>::iterator, std::vector<int>::iterator, int)’
vec_test.cpp:27:46: note: candidate is:
In file included from /usr/local/lib/gcc/i686-pc-linux-gnu/4.7.1/../../../../include/c++/4.7.1/bits/locale_facets.h:50:0,
from /usr/local/lib/gcc/i686-pc-linux-gnu/4.7.1/../../../../include/c++/4.7.1/bits/basic_ios.h:39,
from /usr/local/lib/gcc/i686-pc-linux-gnu/4.7.1/../../../../include/c++/4.7.1/ios:45,
from /usr/local/lib/gcc/i686-pc-linux-gnu/4.7.1/../../../../include/c++/4.7.1/ostream:40,
from /usr/local/lib/gcc/i686-pc-linux-gnu/4.7.1/../../../../include/c++/4.7.1/iostream:40,
from vec_test.cpp:3:
/usr/local/lib/gcc/i686-pc-linux-gnu/4.7.1/../../../../include/c++/4.7.1/bits/streambuf_iterator.h:371:5: note: template<class _CharT2> typename __gnu_cxx::__enable_if<std::__is_char<_CharT2>::__value, std::istreambuf_iterator<_CharT2, std::char_traits<_CharT> > >::__type std::find(std::istreambuf_iterator<_CharT2, std::char_traits<_CharT> >, std::istreambuf_iterator<_CharT2, std::char_traits<_CharT> >, const _CharT2&)
/usr/local/lib/gcc/i686-pc-linux-gnu/4.7.1/../../../../include/c++/4.7.1/bits/streambuf_iterator.h:371:5: note: template argument deduction/substitution failed:
vec_test.cpp:27:46: note: ‘__gnu_cxx::__normal_iterator<int*, std::vector<int> >’ is not derived from ‘std::istreambuf_iterator<_CharT2, std::char_traits<_CharT> >’
This code doesn't do anything since the vector is not initialized with any content but it should compile.
I suspect this is a gcc problem but after lots of digging I'm quit desperate.
Please let me know if anyone encountered this problem and knows how to solve it.

Maybe some file defines a function find in global namespace?
Have you tried specifying full-scope? That's to say, std::find instead of find. It could help deleting that weird line:
using namespace std;
However, it is not what I would expect. I would call it a bug.

Related

no matching function call error using std::find

I have the following function (for testing):
static bool foo(void)
{
std::string name = "name";
std::vector<std::string> test;
std::vector<std::string>::iterator vStart = test.begin();
std::vector<std::string>::iterator vEnd = test.end();
return (std::find(vStart, vEnd, name) == vEnd);
}
And I get a compilation error:
/data/src/fiware-orion/src/lib/common/string.cpp: In function 'bool foo()':
/data/src/fiware-orion/src/lib/common/string.cpp:167:39: error: no matching function for call to 'find(std::vector<std::basic_string<char> >::iterator&, std::vector<std::basic_string<char> >::iterator&, std::string&)'
return (std::find(vStart, vEnd, name) == vEnd);
^
/data/src/fiware-orion/src/lib/common/string.cpp:167:39: note: candidate is:
In file included from /usr/include/c++/4.9/bits/locale_facets.h:48:0,
from /usr/include/c++/4.9/bits/basic_ios.h:37,
from /usr/include/c++/4.9/ios:44,
from /usr/include/c++/4.9/istream:38,
from /usr/include/c++/4.9/sstream:38,
from /data/src/fiware-orion/src/lib/common/string.cpp:31:
/usr/include/c++/4.9/bits/streambuf_iterator.h:369:5: note: template<class _CharT2> typename __gnu_cxx::__enable_if<std::__is_char<_CharT2>::__value, std::istreambuf_iterator<_CharT> >::__type std::find(std::istreambuf_iterator<_CharT>, std::istreambuf_iterator<_CharT>, const _CharT2&)
find(istreambuf_iterator<_CharT> __first,
^
/usr/include/c++/4.9/bits/streambuf_iterator.h:369:5: note: template argument deduction/substitution failed:
/data/src/fiware-orion/src/lib/common/string.cpp:167:39: note: '__gnu_cxx::__normal_iterator<std::basic_string<char>*, std::vector<std::basic_string<char> > >' is not derived from 'std::istreambuf_iterator<_CharT>'
return (std::find(vStart, vEnd, name) == vEnd);
Maybe the message which points to the problem is this:
template argument deduction/substitution failed:
but as far as I undersand the concrete classes used in the find() function argument (std::vector<std::string>::iterator, std::vector<std::string>::iterator and std::string) are clear.
What's specially surprises me is that this same code fragment for foo() function is working verbatim in other parts of my code (i.e. other .cpp files) so maybe it is related somehow with the #include chain in a way I'm not able to deduce or trace...
Any help is welcome!
There is no find from #include <algorithm> in the error message, only the one from streambuf_iterator.h. Add #include <algorithm>.
You are returning an iterator, but your function declaration is 'void'
I think you forgot to include <algorithm>
Please add this #include <algorithm>

Initialization of a templated data member cryptic error

This is my tmp.hpp:
#include <cstdlib>
#include <utility>
#include <unordered_map>
using namespace std;
struct int_int_hasher {
size_t operator()(pair<int, int> const& p) const {
return static_cast<size_t>(p.first) << 32 | p.second;
}
};
template<class T, class H>
class BiBag {
unordered_map<T, uint, H> t_to_id_;
};
And simple tmp.cpp:
#include "tmp.hpp"
class tmp {
BiBag<pair<int, int>, int_int_hasher> tt =
BiBag<std::pair<int, int>, int_int_hasher>();
};
The error message is beyond my understanding:
g++ -std=c++11 -O2 tmp.cpp -lm -o tmp
tmp.cpp:6:32: error: expected ‘;’ at end of member declaration
BiBag<std::pair<int, int>, int_int_hasher>();
^
tmp.cpp:6:32: error: declaration of ‘BiBag<std::pair<int, int>, int_int_hasher> tmp::int_int_hasher’ [-fpermissive]
In file included from tmp.cpp:2:0:
tmp.hpp:7:8: error: changes meaning of ‘int_int_hasher’ from ‘struct int_int_hasher’ [-fpermissive]
struct int_int_hasher {
^
tmp.cpp:6:46: error: expected unqualified-id before ‘>’ token
BiBag<std::pair<int, int>, int_int_hasher>();
^
tmp.cpp:6:16: error: wrong number of template arguments (1, should be 2)
BiBag<std::pair<int, int>, int_int_hasher>();
^
If I remove the hasher from the picture and replace the map with a simple <int,int> map I get no error.
Thank you.

How to insert a const std::shared_ptr into a std::map

Consider the following code:
#include <string>
#include <map>
#include <memory>
#include <utility>
#include <iostream>
typedef std::shared_ptr<const std::string> ConstDataTypePtr;
typedef std::map<std::string, ConstDataTypePtr> StrDataTypeMap;
int main()
{
StrDataTypeMap m_nameToType;
ConstDataTypePtr vp_int8(new std::string("RGH"));
m_nameToType.insert(std::make_pair<std::string, ConstDataTypePtr>("int8_t", vp_int8));
return 0;
}
You must compile it with: g++ -std=c++11 <filename>.cpp.
It gives the following error:
testO.cpp: In function ‘int main()’:
testO.cpp:14:88: error: no matching function for call to ‘make_pair(const char [7], ConstDataTypePtr&)’
m_nameToType.insert(std::make_pair<std::string, ConstDataTypePtr>("int8_t", vp_int8));
^
testO.cpp:14:88: note: candidate is:
In file included from /usr/include/c++/4.8.2/bits/stl_algobase.h:64:0,
from /usr/include/c++/4.8.2/bits/char_traits.h:39,
from /usr/include/c++/4.8.2/string:40,
from testO.cpp:1:
/usr/include/c++/4.8.2/bits/stl_pair.h:276:5: note: template<class _T1, class _T2> constexpr std::pair<typename std::__decay_and_strip<_Tp>::__type, typename std::__decay_and_strip<_T2>::__type> std::make_pair(_T1&&, _T2&&)
make_pair(_T1&& __x, _T2&& __y)
^
/usr/include/c++/4.8.2/bits/stl_pair.h:276:5: note: template argument deduction/substitution failed:
testO.cpp:14:88: note: cannot convert ‘vp_int8’ (type ‘ConstDataTypePtr {aka std::shared_ptr<const std::basic_string<char> >}’) to type ‘std::shared_ptr<const std::basic_string<char> >&&’
m_nameToType.insert(std::make_pair<std::string, ConstDataTypePtr>("int8_t", vp_int8));
From what I am reading of the error, the compiler is expecting an r-value when I am trying to insert into the map. Why? What mistake have I made here?
Kindly note that I created this snippet from some existing code which is part of a large code-base. It is probably also worth mentioning that the snippet has been taken from a code base which was run on Windows and I have the task of porting it to Linux. The original author had used std::tr1::shared_ptr. I modified it to use std::shared_ptr. I didn't expect any repercussions because of this change.
The whole point of std::make_pair is to let compiler deduce types. If you want to provide type, use std::pair<K, V>
So
m_nameToType.insert(std::make_pair<std::string, std::string>("int8_t", vp_int8));
should be:
m_nameToType.insert(std::make_pair("int8_t", vp_int8));
or
m_nameToType.insert(std::pair<const std::string, ConstDataTypePtr>("int8_t", vp_int8));
or simply:
m_nameToType.emplace("int8_t", vp_int8);
#include <memory>
#include <map>
#include <string>
int main() {
using shared_data = std::shared_ptr<const std::string>;
std::map<std::string, shared_data> map;
map.insert(std::make_pair(
"something",
shared_data(new std::string("something else"))
));
return 0;
}
see: http://ideone.com/4AQfqd
Back to your problem;
testO.cpp:14:83: note: cannot convert ‘vp_int8’ (type ‘ConstDataTypePtr {aka std::shared_ptr >}’) to type ‘std::basic_string&&’
m_nameToType.insert(std::make_pair("int8_t", vp_int8));
What you have:
std::make_pair<std::string, std::string>(some_string, TOTALLY_NOT_A_STRING)
You gave wrong types to the std::make_pair template. Just change
m_nameToType.insert(std::make_pair<std::string, std::string>("int8_t", vp_int8));
Into
m_nameToType.insert(std::make_pair<std::string, ConstDataTypePtr>(std::string("int8_t"), vp_int8));
(note the std::make_pair<std::string, ConstDataTypePtr> part)
EDIT: or don't provide template params at all, as someone suggested in comment.
Don't mention the types in the template in make_pair function.
m_nameToType.insert(std::make_pair("int8_t", vp_int8));

What's wrong of this use of boost::lambda::bind?

I'm trying to use boost::lambda::bind() to define a predicate that I pass to the find_if algorithm in Boost.Range. Specifically, I want to search a vector of structures to find the first entry where a particular member has a specified value. My example is as follows:
#include <boost/lambda/bind.hpp>
#include <boost/range/algorithm/find_if.hpp>
#include <vector>
using namespace std;
using namespace boost;
using namespace boost::lambda;
struct foo
{
string s;
int x;
};
int main()
{
// create list and add a couple entries
vector<foo> fooList;
foo f1 = {"abc", 1};
foo f2 = {"def", 2};
fooList.push_back(f1);
fooList.push_back(f2);
// search for a value with the desired member
// fails with a compile error!
range_iterator<vector<foo> > it = find_if(fooList, boost::lambda::bind(&foo::s, _1) == string("abc"));
return 0;
}
When I try to compile this (under gcc 4.7.2), I get the typical spew of template instantiation errors, indicating that there was no operator== found that is compatible with the type returned by bind() and a const char []. I've tried this with other types also, such as int, with the same result.
I must be missing some small detail of bind() usage, but I can't see it; it seems like this sort of thing should work based upon the documentation. Am I wrong there?
Edit: Here is the first part of the compiler output:
test.cc:24:92: error: no match for ‘operator==’ in ‘boost::lambda::bind(const Arg1&, const Arg2&) [with Arg1 = std::basic_string<char> foo::*; Arg2 = boost::lambda::lambda_functor<boost::lambda::placeholder<1> >; typename boost::lambda::detail::bind_tuple_mapper<const Arg1, const Arg2>::type = boost::tuples::tuple<std::basic_string<char> foo::* const, const boost::lambda::lambda_functor<boost::lambda::placeholder<1> >, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type>]((* & boost::lambda::{anonymous}::_1)) == "abc"’
Turns out that I wasn't including the required headers. It appears that <boost/lambda/bind.hpp> only brings in bind functionality, and the operator overloads for the resulting type are not included. If I add #include <boost/lambda/lambda.hpp> to the above, then it resolves the compiler error that I referenced. The final revised code (fixing another error in the type of the return value from find_if()) is as follows:
#include <boost/lambda/bind.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/range/algorithm/find_if.hpp>
#include <string>
#include <vector>
using namespace std;
using namespace boost;
using namespace boost::lambda;
struct foo
{
string s;
int x;
};
int main()
{
// create list and add a couple entries
vector<foo> fooList;
foo f1 = {"abc", 1};
foo f2 = {"def", 2};
fooList.push_back(f1);
fooList.push_back(f2);
// search for a value with the desired member
typename range_iterator<vector<foo> >::type it = find_if(fooList, bind(&foo::s, _1) == "abc");
return 0;
}

How to use bind1st and bind2nd?

I would like to learn how to use binding functions.
Here is the idea:
I have this function which takes to parameters:
void print_i(int t, std::string separator)
{
std::cout << t << separator;
}
And I would like to do:
std::vector<int> elements;
// ...
for_each(elements.begin(), elements.end(), std::bind2nd(print_i, '\n'));
But it does not work !
Here is what I get:
/usr/include/c++/4.3/backward/binders.h: In instantiation of ‘std::binder2nd<void ()(int, std::string)>’:
main.cpp:72: instantiated from here
/usr/include/c++/4.3/backward/binders.h:138: error: ‘void ()(int, std::string)’ is not a class, struct, or union type
/usr/include/c++/4.3/backward/binders.h:141: error: ‘void ()(int, std::string)’ is not a class, struct, or union type
/usr/include/c++/4.3/backward/binders.h:145: error: ‘void ()(int, std::string)’ is not a class, struct, or union type
/usr/include/c++/4.3/backward/binders.h:149: error: ‘void ()(int, std::string)’ is not a class, struct, or union type
/usr/include/c++/4.3/backward/binders.h:155: error: ‘void ()(int, std::string)’ is not a class, struct, or union type
/usr/include/c++/4.3/backward/binders.h:140: error: field ‘std::binder2nd<void ()(int, std::string)>::op’ invalidly declared function type
/usr/include/c++/4.3/backward/binders.h: In function ‘std::binder2nd<_Operation> std::bind2nd(const _Operation&, const _Tp&) [with _Operation = void ()(int, std::string), _Tp = char]’:
main.cpp:72: instantiated from here
/usr/include/c++/4.3/backward/binders.h:164: error: ‘void ()(int, std::string)’ is not a class, struct, or union type
/usr/include/c++/4.3/bits/stl_algo.h: In function ‘_Funct std::for_each(_IIter, _IIter, _Funct) [with _IIter = __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, _Funct = std::binder2nd<void ()(int, std::string)>]’:
main.cpp:72: instantiated from here
/usr/include/c++/4.3/bits/stl_algo.h:3791: error: no match for call to ‘(std::binder2nd<void ()(int, std::string)>) (int&)’
make: *** [all] Error 1
I could use functor, but it is quicker to use binding.
Thanks!
You need to use a Copyable/Refrencable object, the following works:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>
void print_i(int t, std::string separator)
{
std::cout << t << separator;
}
int main()
{
std::vector<int> elements;
std::string delim = "\n";
for_each(elements.begin(),
elements.end(),
std::bind2nd(std::ptr_fun(&print_i),delim));
return 0;
}
Normally you can get the same effect by simply doing the following:
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
int main()
{
std::vector<int> elements;
std::copy(elements.begin(),
elements.end(),
std::ostream_iterator<int>(std::cout,"\n"));
return 0;
}
Also assuming you have access to TR1 in the STL you're using, its always best to revise/replace any uses of bind1st and bind2nd with std::bind
The argument to bind2nd must be an AdaptableBinaryFunction. A plain binary function does not fulfill this requirement (an adaptable function required typedefs for its return and argument types, a plain function type does not provide any typedefs). You could use std::bind which is probably the better choice anyway.
You need to do the following steps:
1. create a struct (or class) that inherits from std::binary_function
2. define your predicate function in the operator() member function of the struct created in step 1
3. use bind2nd to bind an appropriate value to the struct created in step 1
I have done all this in an example. You can read the article and download the complete code on the following link: bind and find
These functions are deprecated since C++11 and removed in C++17. As mentioned in one comment above, the better solution now is to use std::bind and the placeholders:
void callable(int a, int b);
auto f = std::bind1st(&callable, 42); // returns a 1-arg function
becomes:
// returns a 1-arg function
auto f = std::bind(&callable, 42, std::placeholders::_1);