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>
Related
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));
I'm trying to convert a vector<int> to a vector<string>. Using std::transform I used std::to_string to convert the int to string but I keep getting an error. Here's my code
#include <vector>
#include <iostream>
#include <algorithm>
#include <string>
int main(){
std::vector<int> v_int;
std::vector<std::string> v_str;
for(int i = 0;i<5;++i)
v_int.push_back(i);
v_str.resize(v_int.size());
std::transform(v_int.begin(),v_int.end(),v_str.begin(),std::to_string);
}
but I'm getting this error
no matching function for call to 'transform'
std::transform(v_int.begin(),v_int.end(),v_str.begin(),std::to_string);
^~~~~~~~~~~~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/algorithm:1951:1: note:
candidate template ignored: couldn't infer template argument
'_UnaryOperation'
transform(_InputIterator __first, _InputIterator __last, _OutputIterato...
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/algorithm:1961:1: note:
candidate function template not viable: requires 5 arguments, but 4 were
provided
transform(_InputIterator1 __first1, _InputIterator1 __last1, _InputItera...
std::to_string is an overloaded function, so you'll need to provide a cast to disambiguate
std::transform(v_int.begin(),v_int.end(),v_str.begin(),
static_cast<std::string(*)(int)>(std::to_string));
Or use a lambda
std::transform(v_int.begin(),v_int.end(),v_str.begin(),
[](int i){ return std::to_string(i); });
I can't tell if I'm just missing something obvious here but I cannot seem to get find_if to work.
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
bool isspace(char c)
{
return c == ' ';
}
int main()
{
string text = "This is the text";
string::iterator it = find_if(text.begin(), text.end(), isspace);
cout << *it << endl;
return 0;
}
I've looked at the example here, http://www.cplusplus.com/reference/algorithm/find_if/, which compiles and runs but I cannot see the difference between that and my program other than the vector -> string thing but I don't see why that would make a difference.
I know cctype has the better functions for isspace but I wanted to make sure that wasn't messing me up.
My error:
test.cpp: In function ‘int main()’:
test.cpp:16:68: error: no matching function for call to ‘find_if(std::basic_string<char>::iterator, std::basic_string<char>::iterator, <unresolved overloaded function type>)’
string::iterator it = find_if(text.begin(), text.end(), isspace);
^
test.cpp:16:68: note: candidate is:
In file included from /usr/include/c++/4.8/algorithm:62:0,
from test.cpp:3:
/usr/include/c++/4.8/bits/stl_algo.h:4456:5: note: template<class _IIter, class _Predicate> _IIter std::find_if(_IIter, _IIter, _Predicate)
find_if(_InputIterator __first, _InputIterator __last,
^
/usr/include/c++/4.8/bits/stl_algo.h:4456:5: note: template argument deduction/substitution failed:
test.cpp:16:68: note: couldn't deduce template parameter ‘_Predicate’
string::iterator it = find_if(text.begin(), text.end(), isspace);
^
The key part of the error is:
test.cpp:16:68: error: no matching function for call to ‘find_if(
std::basic_string<char>::iterator,
std::basic_string<char>::iterator,
<unresolved overloaded function type>)’ // <==
Unresolved overloaded function type!? That's because you defined:
bool isspace(char );
But there is already one named isspace:
bool isspace(int );
and another named std::isspace that you bring in with using:
template <class charT>
bool isspace(charT, const locale&);
And the template can't know which one it is you want. So you can either specify it explicitly:
string::iterator it = find_if(
text.begin(),
text.end(),
static_cast<bool(*)(char)>(isspace)); // make sure yours gets called
Or, simpler, just change your name.
Or, simplest, just delete yours and stop using namespace std;. That way, isspace unambiguously references exactly the one function you wanted to use in the first place.
I want to split by comma, and I have the following class which is instantiated with a comma-separated line. The class is as follows:
#include <sstream>
#include <stdio.h>
#include <iostream>
#include <ctime>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <vector>
#include <string>
#include <set>
#include <vector>
#include <boost/tokenizer.hpp>
class Packet {
public:
int packetEndDateTime;
int creationTimeStamp;
std::string mydatetime;
std::string micses;
std::string message_type;
std::string teid;
std::string teid_cp;
std::string teid_data;
std::string apn;
std::string msisdn;
std::string cause;
std::string causeText;
std::string responseDate;
std::string allData;
std::string fields[9];
int fieldPos = 0;
/*
boost::char_separator<char> sep(",", "|", boost::keep_empty_tokens);
typedef boost::tokenizer<boost::char_separator<char>> tokenizer;
*/
typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
boost::char_separator<char> sep(",", "|", boost::keep_empty_tokens); // empty token policy
Packet(){ }
Packet(std::string inMessage){
set_message(inMessage);
}
void set_message(std::string inMessage){
allData = inMessage;
tokenizer tokens(inMessage, sep);
for ( tokenizer::iterator tok_iter = tokens.begin(); tok_iter != tokens.end(); ++tok_iter ){
fields[fieldPos] = *tok_iter;
fieldPos++;
}
mydatetime = fields[0];
message_type = fields[1];
teid = fields[2];
teid_cp = fields[3];
teid_data = fields[4];
cause = fields[5];
apn = fields[6];
msisdn = fields[7];
}
};
The compiler is coming back with:
g++ -o ggsnGiParser welcome.cc -lboost_filesystem -lboost_program_options -lboost_system -std=c++11
In file included from welcome.cc:49:0:
Packet.hpp:39:41: error: expected identifier before ','
Packet.hpp:39:41: error: expected ‘,’ or ‘...’ before ','
Packet.hpp: In member function ‘void Packet::set_message(std::string)’:
Packet.hpp:51:40: error: no matching function for call to ‘boost::tokenizer<boost::char_separator<char> >::tokenizer(std::string&, <unresolved overloaded function type>)’
Packet.hpp:51:40: note: candidates are:
In file included from Packet.hpp:12:0,
from welcome.cc:49:
/usr/include/boost/tokenizer.hpp:62:5: note: template<class Container> boost::tokenizer::tokenizer(const Container&, const TokenizerFunc&)
/usr/include/boost/tokenizer.hpp:62:5: note: template argument deduction/substitution failed:
In file included from welcome.cc:49:0:
Packet.hpp:51:40: note: cannot convert ‘((Packet*)this)->Packet::sep’ (type ‘<unresolved overloaded function type>’) to type ‘const boost::char_separator<char>&’
In file included from Packet.hpp:12:0,
from welcome.cc:49:
/usr/include/boost/tokenizer.hpp:58:5: note: template<class Container> boost::tokenizer::tokenizer(const Container&)
/usr/include/boost/tokenizer.hpp:58:5: note: template argument deduction/substitution failed:
In file included from welcome.cc:49:0:
Packet.hpp:51:40: note: candidate expects 1 argument, 2 provided
In file included from Packet.hpp:12:0,
from welcome.cc:49:
/usr/include/boost/tokenizer.hpp:53:5: note: boost::tokenizer<TokenizerFunc, Iterator, Type>::tokenizer(Iterator, Iterator, const TokenizerFunc&) [with TokenizerFunc = boost::char_separator<char>; Iterator = __gnu_cxx::__normal_iterator<const char*, std::basic_string<char> >; Type = std::basic_string<char>]
/usr/include/boost/tokenizer.hpp:53:5: note: no known conversion for argument 1 from ‘std::string {aka std::basic_string<char>}’ to ‘__gnu_cxx::__normal_iterator<const char*, std::basic_string<char> >’
/usr/include/boost/tokenizer.hpp:32:9: note: boost::tokenizer<boost::char_separator<char> >::tokenizer(const boost::tokenizer<boost::char_separator<char> >&)
/usr/include/boost/tokenizer.hpp:32:9: note: candidate expects 1 argument, 2 provided
/usr/include/boost/tokenizer.hpp:32:9: note: boost::tokenizer<boost::char_separator<char> >::tokenizer(boost::tokenizer<boost::char_separator<char> >&&)
/usr/include/boost/tokenizer.hpp:32:9: note: candidate expects 1 argument, 2 provided
And I really don't understand where the problem might be...
Any help is greatly appreciated!
David
Replace
boost::char_separator<char> sep(",", "|", boost::keep_empty_tokens); // empty token policy
with
boost::char_separator<char> sep = {",", "|", boost::keep_empty_tokens}; // empty token policy
When constructing within a class declaration, you have to avoid that particular () syntax.
There may be more errors hidden by this.
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);