I'm working on a program that uses the Boost regular expressions library, and I'm running into an issue where while trying to call the boost::regex_match() function, I'm getting a strange error that I've never encountered before. Here is the relevant code.
boost::regex pattern("REGEX REDACTED");
boost::cmatch what;
XERCES_STD_QUALIFIER cout << "Enter XML Document-Building Commands" << XERCES_STD_QUALIFIER endl;
while(true) {
// Take the input from the user.
std::string input;
XERCES_STD_QUALIFIER cout << ">> ";
XERCES_STD_QUALIFIER getline(in, input);
if(boost::regex_match(input, what, pattern)) {
// whatever
}
}
This is almost exactly what I took out of example code from a similar program my instructor provided for this assignment. But when I try to compile, I get this error. If it helps, I'm using NetBeans 8.
XMLDoc.cpp: In member function ‘void XMLDoc::createDoc(std::istream&)’:
XMLDoc.cpp:164:51: error: no matching function for call to ‘regex_match(std::string&, boost::cmatch&, boost::regex&)’
XMLDoc.cpp:164:51: note: candidates are:
In file included from /usr/include/boost/regex/v4/regex.hpp:145:0,
from /usr/include/boost/regex.hpp:31,
from XMLDoc.cpp:13:
/usr/include/boost/regex/v4/regex_match.hpp:44:6: note: template<class BidiIterator, class Allocator, class charT, class traits> bool boost::regex_match(BidiIterator, BidiIterator, boost::match_results<Iterator, Allocator>&, const boost::basic_regex<charT, traits>&, boost::regex_constants::match_flag_type)
/usr/include/boost/regex/v4/regex_match.hpp:44:6: note: template argument deduction/substitution failed:
XMLDoc.cpp:164:51: note: deduced conflicting types for parameter ‘BidiIterator’ (‘std::basic_string<char>’ and ‘boost::match_results<const char*>’)
In file included from /usr/include/boost/regex/v4/regex.hpp:145:0,
from /usr/include/boost/regex.hpp:31,
from XMLDoc.cpp:13:
/usr/include/boost/regex/v4/regex_match.hpp:53:6: note: template<class iterator, class charT, class traits> bool boost::regex_match(iterator, iterator, const boost::basic_regex<charT, traits>&, boost::regex_constants::match_flag_type)
/usr/include/boost/regex/v4/regex_match.hpp:53:6: note: template argument deduction/substitution failed:
XMLDoc.cpp:164:51: note: deduced conflicting types for parameter ‘iterator’ (‘std::basic_string<char>’ and ‘boost::match_results<const char*>’)
In file included from /usr/include/boost/regex/v4/regex.hpp:145:0,
from /usr/include/boost/regex.hpp:31,
from XMLDoc.cpp:13:
/usr/include/boost/regex/v4/regex_match.hpp:68:13: note: template<class charT, class Allocator, class traits> bool boost::regex_match(const charT*, boost::match_results<const charT*, Allocator>&, const boost::basic_regex<charT, traits2>&, boost::regex_constants::match_flag_type)
/usr/include/boost/regex/v4/regex_match.hpp:68:13: note: template argument deduction/substitution failed:
XMLDoc.cpp:164:51: note: mismatched types ‘const charT*’ and ‘std::basic_string<char>’
In file included from /usr/include/boost/regex/v4/regex.hpp:145:0,
from /usr/include/boost/regex.hpp:31,
from XMLDoc.cpp:13:
/usr/include/boost/regex/v4/regex_match.hpp:77:13: note: bool boost::regex_match(const std::basic_string<charT, ST, SA>&, boost::match_results<typename std::basic_string<charT, ST, SA>::const_iterator, Allocator>&, const boost::basic_regex<charT, traits>&, boost::regex_constants::match_flag_type) [with ST = std::char_traits<char>; SA = std::allocator<char>; Allocator = std::allocator<boost::sub_match<const char*> >; charT = char; traits = boost::regex_traits<char>; typename std::basic_string<charT, ST, SA>::const_iterator = __gnu_cxx::__normal_iterator<const char*, std::basic_string<char> >; boost::regex_constants::match_flag_type = boost::regex_constants::_match_flags]
/usr/include/boost/regex/v4/regex_match.hpp:77:13: note: no known conversion for argument 2 from ‘boost::cmatch {aka boost::match_results<const char*>}’ to ‘boost::match_results<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char> >, std::allocator<boost::sub_match<const char*> > >&’
/usr/include/boost/regex/v4/regex_match.hpp:85:13: note: template<class charT, class traits> bool boost::regex_match(const charT*, const boost::basic_regex<charT, traits>&, boost::regex_constants::match_flag_type)
/usr/include/boost/regex/v4/regex_match.hpp:85:13: note: template argument deduction/substitution failed:
XMLDoc.cpp:164:51: note: mismatched types ‘const charT*’ and ‘std::basic_string<char>’
In file included from /usr/include/boost/regex/v4/regex.hpp:145:0,
from /usr/include/boost/regex.hpp:31,
from XMLDoc.cpp:13:
/usr/include/boost/regex/v4/regex_match.hpp:94:13: note: template<class ST, class SA, class charT, class traits> bool boost::regex_match(const std::basic_string<charT, ST, SA>&, const boost::basic_regex<charT, traits>&, boost::regex_constants::match_flag_type)
/usr/include/boost/regex/v4/regex_match.hpp:94:13: note: template argument deduction/substitution failed:
XMLDoc.cpp:164:51: note: ‘boost::cmatch {aka boost::match_results<const char*>}’ is not derived from ‘const boost::basic_regex<charT, traits>’
Can someone help me out here? I'm certain I included the library properly because I have another project with the exact same Linker properties that uses the boost::regex_match function (minus the cmatch object parameter), and it works just fine.
If you're going to use a std::string input, you have to use boost::smatch instead of boost::cmatch. See http://www.boost.org/doc/libs/1_57_0/libs/regex/doc/html/boost_regex/ref/match_results.html. So all you need to do is change
boost::cmatch what;
to
boost::smatch what;
Related
I’m using Visual Studio and I'm reacquainting myself with C++ before taking a few classes.
This is an old script that used to compile, but now istream is giving me a few syntax errors. If anyone can lead me in the right direction, that would be great.
Fraction.h
friend istream& operator >> (istream& in, const Fraction& f);
Fraction.cpp
istream& operator >> (istream& in, const Fraction& f) {
cout << "Enter numerator" << endl;
in >> f.num;// error line
cout << "Enter denominator" << endl;
in >> f.denom; // error line
return in;
}
Visual Studio Error Summary
Terminal Error Bottom Small Portion
/usr/include/c++/8/istream:803:5: note: template argument deduction/substitution failed:
/home/spamandsons/projects/laney/Fraction.cpp:188:13: note: cannot convert ‘f.Fraction::denom’ (type ‘const int’) to type ‘unsigned char*’
in >> f.denom;
~~^~~~~
In file included from /usr/include/c++/8/iostream:40,
from /home/spamandsons/projects/laney/Fraction.cpp:2:
/usr/include/c++/8/istream:808:5: note: candidate: ‘template<class _Traits> std::basic_istream<char, _Traits>& std::operator>>(std::basic_istream<char, _Traits>&, signed char*)’
operator>>(basic_istream<char, _Traits>& __in, signed char* __s)
^~~~~~~~
/usr/include/c++/8/istream:808:5: note: template argument deduction/substitution failed:
/home/spamandsons/projects/laney/Fraction.cpp:188:13: note: cannot convert ‘f.Fraction::denom’ (type ‘const int’) to type ‘signed char*’
in >> f.denom;
~~^~~~~
In file included from /usr/include/c++/8/iostream:40,
from /home/spamandsons/projects/laney/Fraction.cpp:2:
/usr/include/c++/8/istream:980:5: note: candidate: ‘template<class _Istream, class _Tp> typename std::enable_if<std::__and_<std::__not_<std::is_lvalue_reference<_Tp> >, std::__is_convertible_to_basic_istream<_Istream>, std::__is_extractable<typename std::__is_convertible_to_basic_istream<_Tp>::__istream_type, _Tp&&, void> >::value, typename std::__is_convertible_to_basic_istream<_Tp>::__istream_type>::type std::operator>>(_Istream&&, _Tp&&)’
operator>>(_Istream&& __is, _Tp&& __x)
^~~~~~~~
/usr/include/c++/8/istream:980:5: note: template argument deduction/substitution failed:
/usr/include/c++/8/istream: In substitution of ‘template<class _Istream, class _Tp> typename std::enable_if<std::__and_<std::__not_<std::is_lvalue_reference<_Tp> >, std::__is_convertible_to_basic_istream<_Istream>, std::__is_extractable<typename std::__is_convertible_to_basic_istream<_Tp>::__istream_type, _Tp&&, void> >::value, typename std::__is_convertible_to_basic_istream<_Tp>::__istream_type>::type std::operator>>(_Istream&&, _Tp&&) [with _Istream = std::basic_istream<char>&; _Tp = const int&]’:
/home/spamandsons/projects/laney/Fraction.cpp:188:13: required from here
/usr/include/c++/8/istream:980:5: error: no type named ‘type’ in ‘struct std::enable_if<false, std::basic_istream<char>&>’
The terminal process terminated with exit code: -1.
Terminal will be reused by tasks, press any key to close it.
Because it takes reference to CONST type. const Fraction& f, it must not be (just remove "const" in the both declaration and definition), the stream input operator is about to modify this object. Instead, const should be used in the stream output operator (e.g. std::ostream& operator<<(std::ostream& os, const Fraction& f)), where outputted object is not supposed to be modified.
I am using unordered map for the first time and that with custom objects. I tried to write the below functions. There are errors that I need help with.
This is the class.
class Node
{
public:
int g= 0, h=0;
char val; //Char value in the grid
pair<int,int> pos,parent;
bool par_prsnt = false; //Bool to check if the parent is set
Node(pair<int,int>nodePos,char value)
{
pos=nodePos;
val=value;
}
int move_cost(Node other)
{
if (val=='.')
return 0;
else
return 1;
}
pair<int,int> get_pos() const
{
return pos;
}
void set_parent(pair<int,int> par)
{
parent = par;
par_prsnt = true;
}
};
Below is the custom functions:
// Custom Hasher for Class Node, to be used for Unordered_set
struct NodeHasher
{
template <typename T, typename U>
size_t
const operator()(const Node &obj)
{
pair<T,U> position;
position = obj.get_pos();
return 3* std::hash<T>()(position.first) + std::hash<U>()(position.second) ;
}
};
// Custom Comparator for Class Node, to be used for Unordered_set
struct NodeComparator
{
bool
const operator()(const Node &obj1, const Node &obj2) const
{
if (obj1.get_pos() == obj2.get_pos())
return true;
return false;
}
};
I get the following errors:
Player 1: compilation error
In file included from /usr/include/c++/7/bits/hashtable.h:35:0,
from /usr/include/c++/7/unordered_map:47,
from /usr/include/x86_64-linux-gnu/c++/7/bits/stdc++.h:117,
solution.cc:7:
/usr/include/c++/7/bits/hashtable_policy.h: In instantiation of ‘struct std::__detail::__is_noexcept_hash’:
/usr/include/c++/7/type_traits:143:12: required from ‘struct std::__and_, std::__detail::__is_noexcept_hash >’
/usr/include/c++/7/type_traits:154:31: required from ‘struct std::__not_, std::__detail::__is_noexcept_hash > >’
/usr/include/c++/7/bits/unordered_set.h:98:63: required from ‘class std::unordered_set’
solution.cc:119:51: required from here
/usr/include/c++/7/bits/hashtable_policy.h:87:34: error: no match for call to ‘(const NodeHasher) (const Node&)’
noexcept(declval()(declval()))>
~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
solution.cc:83:9: note: candidate: template const size_t NodeHasher::operator()(const Node&)
const operator()(const Node &obj)
^~~~~~~~
solution.cc:83:9: note: template argument deduction/substitution failed:
In file included from /usr/include/c++/7/bits/hashtable.h:35:0,
from /usr/include/c++/7/unordered_map:47,
from /usr/include/x86_64-linux-gnu/c++/7/bits/stdc++.h:117,
solution.cc:7:
/usr/include/c++/7/bits/hashtable_policy.h:87:34: note: couldn't deduce template parameter ‘T’
noexcept(declval()(declval()))>
~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/7/bits/move.h:54:0,
from /usr/include/c++/7/bits/stl_pair.h:59,
from /usr/include/c++/7/bits/stl_algobase.h:64,
from /usr/include/c++/7/vector:60,
solution.cc:3:
/usr/include/c++/7/type_traits: In instantiation of ‘struct std::__not_, std::__detail::__is_noexcept_hash > >’:
/usr/include/c++/7/bits/unordered_set.h:98:63: required from ‘class std::unordered_set’
solution.cc:119:51: required from here
/usr/include/c++/7/type_traits:154:31: error: ‘value’ is not a member of ‘std::__and_, std::__detail::__is_noexcept_hash >’
: public __bool_constant
^~~~~~~~~~~~~~~~
In file included from /usr/include/c++/7/unordered_set:48:0,
from /usr/include/x86_64-linux-gnu/c++/7/bits/stdc++.h:118,
solution.cc:7:
/usr/include/c++/7/bits/unordered_set.h: In instantiation of ‘class std::unordered_set’:
solution.cc:119:51: required from here
/usr/include/c++/7/bits/unordered_set.h:98:63: error: ‘value’ is not a member of ‘std::__not_, std::__detail::__is_noexcept_hash > >’
typedef __uset_hashtable _Hashtable;
^~~~~~~~~~
/usr/include/c++/7/bits/unordered_set.h:105:45: error: ‘value’ is not a member of ‘std::__not_, std::__detail::__is_noexcept_hash > >’
typedef typename _Hashtable::key_type key_type;
^~~~~~~~
The error list is much longer, I think this much maybe enough for someone to understand the error. I referred this page for the custom functions : http://thispointer.com/how-to-use-unordered_set-with-user-defined-classes-tutorial-example/. Any suggestions? Thanks for reading.
Edit 1:
Unordered_set creation:
unordered_set<Node,NodeHasher,NodeComparator> openList;
Edit 2:
Error in comparison operator.
Player 1: compilation error
In file included from /usr/include/c++/7/bits/stl_algobase.h:71:0,
from /usr/include/c++/7/vector:60,
solution.cc:3:
/usr/include/c++/7/bits/predefined_ops.h: In instantiation of ‘bool __gnu_cxx::__ops::_Iter_equals_val::operator()(_Iterator) [with _Iterator = __gnu_cxx::__normal_iterator >; _Value = const Node]’:
/usr/include/c++/7/bits/stl_algo.h:120:14: required from ‘_RandomAccessIterator std::__find_if(_RandomAccessIterator, _RandomAccessIterator, _Predicate, std::random_access_iterator_tag) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator >; _Predicate = __gnu_cxx::__ops::_Iter_equals_val]’
/usr/include/c++/7/bits/stl_algo.h:161:23: required from ‘_Iterator std::__find_if(_Iterator, _Iterator, _Predicate) [with _Iterator = __gnu_cxx::__normal_iterator >; _Predicate = __gnu_cxx::__ops::_Iter_equals_val]’
/usr/include/c++/7/bits/stl_algo.h:3907:28: required from ‘_IIter std::find(_IIter, _IIter, const _Tp&) [with _IIter = __gnu_cxx::__normal_iterator >; _Tp = Node]’
solution.cc:147:73: required from here
/usr/include/c++/7/bits/predefined_ops.h:241:17: error: no match for ‘operator==’ (operand types are ‘Node’ and ‘const Node’)
{ return *__it == _M_value; }
~~~~~~^~~~~~~~~~~
In file included from /usr/include/c++/7/bits/stl_algobase.h:67:0,
from /usr/include/c++/7/vector:60,
solution.cc:3:
/usr/include/c++/7/bits/stl_iterator.h:859:5: note: candidate: template bool __gnu_cxx::operator==(const __gnu_cxx::__normal_iterator&, const __gnu_cxx::__normal_iterator&)
operator==(const __normal_iterator& __lhs,
^~~~~~~~
/usr/include/c++/7/bits/stl_iterator.h:859:5: note: template argument deduction/substitution failed:
In file included from /usr/include/c++/7/bits/stl_algobase.h:71:0,
from /usr/include/c++/7/vector:60,
solution.cc:3:
/usr/include/c++/7/bits/predefined_ops.h:241:17: note: ‘Node’ is not derived from ‘const __gnu_cxx::__normal_iterator’
{ return *__it == _M_value; }
~~~~~~^~~~~~~~~~~
In file included from /usr/include/c++/7/bits/stl_algobase.h:67:0,
from /usr/include/c++/7/vector:60,
solution.cc:3:
/usr/include/c++/7/bits/stl_iterator.h:866:5: note: candidate: template bool __gnu_cxx::operator==(const __gnu_cxx::__normal_iterator&, const __gnu_cxx::__normal_iterator&)
operator==(const __normal_iterator& __lhs,
^~~~~~~~
/usr/include/c++/7/bits/stl_iterator.h:866:5: note: template argument deduction/substitution failed:
In file included from /usr/include/c++/7/bits/stl_algobase.h:71:0,
from /usr/include/c++/7/vector:60,
solution.cc:3:
/usr/include/c++/7/bits/predefined_ops.h:241:17: note: ‘Node’ is not derived from ‘const __gnu_cxx::__normal_iterator’
{ return *__it == _M_value; }
~~~~~~^~~~~~~~~~~
In file included from /usr/include/x86_64-linux-gnu/c++/7/bits/c++allocator.h:33:0,
from /usr/include/c++/7/bits/allocator.h:46,
from /usr/include/c++/7/vector:61,
solution.cc:3:
/usr/include/c++/7/ext/new_allocator.h:155:5: note: candidate: template bool __gnu_cxx::operator==(const __gnu_cxx::new_allocator&, const __gnu_cxx::new_allocator&)
operator==(const new_allocator&, const new_allocator&)
^~~~~~~~
/usr/include/c++/7/ext/new_allocator.h:155:5: note: template argument deduction/substitution failed:
In file included from /usr/include/c++/7/bits/stl_algobase.h:71:0,
from /usr/include/c++/7/vector:60,
solution.cc:3:
/usr/include/c++/7/bits/predefined_ops.h:241:17: note: ‘Node’ is not derived from ‘const __gnu_cxx::new_allocator’
{ return *__it == _M_value; }
~~~~~~^~~~~~~~~~~
solution.cc: In function ‘std::vector aStar(std::vector >&, std::pair, std::pair)’:
solution.cc:173:1: error: control reaches end of non-void function [-Werror=return-type]
}
^
cc1plus: some warnings being treated as errors
struct NodeHasher
{
template <typename T, typename U>
size_t const operator()(const Node &obj)
{
pair<T,U> position;
position = obj.get_pos();
return 3* std::hash<T>()(position.first) + std::hash<U>()(position.second) ;
}
};
The compiler can deduce what T and U are in this case. One solution would be to remove the template and hard code int since you know you are working with a pair of int.
And I believe you misplaced the const specifier -- it should be placed at the end of the declaration
Alternatively, if you want to make NodeHasher work for different types of pair, You can make it a template class instead.
template <typename T, typename U>
struct NodeHasher
{
size_t operator()(const Node &obj) const
{
pair<T, U> position = obj.get_pos();
return 3* std::hash<T>()(position.first) + std::hash<U>()(position.second) ;
}
};
And create your unordered_set as
unordered_set<Node, NodeHasher<int,int>, NodeComparator> us; //T and U are int
What is the rationale for selectively excising template member functions from class interfaces when the arguments do not satisfy various criteria, tested for with enable_if etc? If the member function templates were left in, attempting to use them would fail, and it seems to me, with a more useful compiler error than 'substitution failure' in the more complex case?
If compilation fails either way, what is the argument in favor of these extremely strict SFINAE-based template member function requirements?
Compiler errors 2-5 deep in template code have been found to be nearly impenetrable. You get a spew of template noise.
SFINAE substitution failures usually list a template and say it doesn't work because some argument cannot be deduced, often with the trait that failed displayed. Not perfect, but better than template spew.
What more, such templates can block other ones which are valid.
In addition, you can test if a given method exists and is valid at compile time if you use SFINAE-like techniques; you cannot if the body fails to compile.
Which error message do you find easier to understand. This one with SFINAE?
template <class C, class = decltype(begin(std::declval<C&>())[0])>
void sort_sfinae(C& c) {
std::sort(c.begin(), c.end());
}
main.cpp: In function 'int main()':
main.cpp:11:18: error: no matching function for call to 'sort_sfinae(std::__cxx11::list<int>&)'
sort_sfinae(l);
^
main.cpp:5:6: note: candidate: template<class C, class> void sort_sfinae(C&)
void sort_sfinae(C& c) {
^
main.cpp:5:6: note: template argument deduction/substitution failed:
main.cpp:4:62: error: no match for 'operator[]' (operand types are 'std::__cxx11::list<int>::iterator {aka std::_List_iterator<int>}' and 'int')
template <class C, class = decltype(begin(std::declval<C&>())[0])>
^
Or this one without?
template <class C>
void sort_no_sfinae(C& c) {
std::sort(c.begin(), c.end());
}
In file included from /usr/local/include/c++/5.3.0/algorithm:62:0,
from main.cpp:2:
/usr/local/include/c++/5.3.0/bits/stl_algo.h: In instantiation of 'void std::__sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = std::_List_iterator<int>; _Compare = __gnu_cxx::__ops::_Iter_less_iter]':
/usr/local/include/c++/5.3.0/bits/stl_algo.h:4698:18: required from 'void std::sort(_RAIter, _RAIter) [with _RAIter = std::_List_iterator<int>]'
main.cpp:6:14: required from 'void sort_no_sfinae(C&) [with C = std::__cxx11::list<int>]'
main.cpp:11:21: required from here
/usr/local/include/c++/5.3.0/bits/stl_algo.h:1964:22: error: no match for 'operator-' (operand types are 'std::_List_iterator<int>' and 'std::_List_iterator<int>')
std::__lg(__last - __first) * 2,
^
In file included from /usr/local/include/c++/5.3.0/bits/stl_algobase.h:67:0,
from /usr/local/include/c++/5.3.0/list:60,
from main.cpp:1:
/usr/local/include/c++/5.3.0/bits/stl_iterator.h:328:5: note: candidate: template<class _Iterator> typename std::reverse_iterator<_Iterator>::difference_type std::operator-(const std::reverse_iterator<_Iterator>&, const std::reverse_iterator<_Iterator>&)
operator-(const reverse_iterator<_Iterator>& __x,
^
/usr/local/include/c++/5.3.0/bits/stl_iterator.h:328:5: note: template argument deduction/substitution failed:
In file included from /usr/local/include/c++/5.3.0/algorithm:62:0,
from main.cpp:2:
/usr/local/include/c++/5.3.0/bits/stl_algo.h:1964:22: note: 'std::_List_iterator<int>' is not derived from 'const std::reverse_iterator<_Iterator>'
std::__lg(__last - __first) * 2,
^
In file included from /usr/local/include/c++/5.3.0/bits/stl_algobase.h:67:0,
from /usr/local/include/c++/5.3.0/list:60,
from main.cpp:1:
/usr/local/include/c++/5.3.0/bits/stl_iterator.h:380:5: note: candidate: template<class _IteratorL, class _IteratorR> decltype ((__y.base() - __x.base())) std::operator-(const std::reverse_iterator<_Iterator>&, const std::reverse_iterator<_IteratorR>&)
operator-(const reverse_iterator<_IteratorL>& __x,
^
/usr/local/include/c++/5.3.0/bits/stl_iterator.h:380:5: note: template argument deduction/substitution failed:
In file included from /usr/local/include/c++/5.3.0/algorithm:62:0,
from main.cpp:2:
/usr/local/include/c++/5.3.0/bits/stl_algo.h:1964:22: note: 'std::_List_iterator<int>' is not derived from 'const std::reverse_iterator<_Iterator>'
std::__lg(__last - __first) * 2,
^
In file included from /usr/local/include/c++/5.3.0/bits/stl_algobase.h:67:0,
from /usr/local/include/c++/5.3.0/list:60,
from main.cpp:1:
/usr/local/include/c++/5.3.0/bits/stl_iterator.h:1138:5: note: candidate: template<class _IteratorL, class _IteratorR> decltype ((__x.base() - __y.base())) std::operator-(const std::move_iterator<_Iterator>&, const std::move_iterator<_IteratorR>&)
operator-(const move_iterator<_IteratorL>& __x,
^
/usr/local/include/c++/5.3.0/bits/stl_iterator.h:1138:5: note: template argument deduction/substitution failed:
In file included from /usr/local/include/c++/5.3.0/algorithm:62:0,
from main.cpp:2:
/usr/local/include/c++/5.3.0/bits/stl_algo.h:1964:22: note: 'std::_List_iterator<int>' is not derived from 'const std::move_iterator<_Iterator>'
std::__lg(__last - __first) * 2,
^
In file included from /usr/local/include/c++/5.3.0/bits/stl_algobase.h:67:0,
from /usr/local/include/c++/5.3.0/list:60,
from main.cpp:1:
/usr/local/include/c++/5.3.0/bits/stl_iterator.h:1145:5: note: candidate: template<class _Iterator> decltype ((__x.base() - __y.base())) std::operator-(const std::move_iterator<_Iterator>&, const std::move_iterator<_Iterator>&)
operator-(const move_iterator<_Iterator>& __x,
^
/usr/local/include/c++/5.3.0/bits/stl_iterator.h:1145:5: note: template argument deduction/substitution failed:
In file included from /usr/local/include/c++/5.3.0/algorithm:62:0,
from main.cpp:2:
/usr/local/include/c++/5.3.0/bits/stl_algo.h:1964:22: note: 'std::_List_iterator<int>' is not derived from 'const std::move_iterator<_Iterator>'
std::__lg(__last - __first) * 2,
^
In file included from /usr/local/include/c++/5.3.0/vector:65:0,
from /usr/local/include/c++/5.3.0/bits/random.h:34,
from /usr/local/include/c++/5.3.0/random:49,
from /usr/local/include/c++/5.3.0/bits/stl_algo.h:66,
from /usr/local/include/c++/5.3.0/algorithm:62,
from main.cpp:2:
/usr/local/include/c++/5.3.0/bits/stl_bvector.h:208:3: note: candidate: std::ptrdiff_t std::operator-(const std::_Bit_iterator_base&, const std::_Bit_iterator_base&)
operator-(const _Bit_iterator_base& __x, const _Bit_iterator_base& __y)
^
/usr/local/include/c++/5.3.0/bits/stl_bvector.h:208:3: note: no known conversion for argument 1 from 'std::_List_iterator<int>' to 'const std::_Bit_iterator_base&'
I am fairly new to C++ and wanted to convert a *FILE (such as returned by popen()) to a iostream to be used with functions such as getline etc. I found the following code http://fw-geekycoder.blogspot.co.za/2011/06/how-to-convert-c-file-to-c-iostream.html, as well as similar code from a bunch of places, but the compiler moans about boost::iostreams::stream_buffer<boost::iostreams::file_descriptor_sink> bis(fd); and boost::iostreams::stream_buffer<boost::iostreams::file_descriptor_sink> bis(fd);
#include <iostream>
#include <cstdio>
#include <unistd.h>
#include <boost/iostreams/device/file_descriptor.hpp>
#include <boost/iostreams/stream.hpp>
void write() {
FILE* fp = fopen("whatever.txt", "w");
if (fp == NULL) {
perror("fopen error");
}
int fd = fileno(fp);
boost::iostreams::stream_buffer<boost::iostreams::file_descriptor_sink> bis(fd);
std::ostream os(&bis);
os << "Hello World!" << std::endl;
fclose(fp);
}
void read() {
FILE* fp = fopen("whatever.txt", "r");
if (fp == NULL) {
perror("fopen error");
}
int fd = fileno(fp);
boost::iostreams::stream_buffer<boost::iostreams::file_descriptor_source> bis(fd);
std::istream is(&bis);
while (is) {
std::string line;
std::getline(is, line);
std::cout << line << std::endl;
}
fclose(fp);
}
int main() {
write();
read();
return 0;
}
It seems like my system finds boost, but as if the API or something changed. What is the problem, here is my output from eclipse:
make all
Building file: ../src/boostPopenHandler.cpp
Invoking: GCC C++ Compiler
g++ -D__GXX_EXPERIMENTAL_CXX0X__ -I../../emdw/src -I../../patrecII/src -I../../ -O0 -g3 -Wall -c -fmessage-length=0 -std=c++0x -MMD -MP -MF"src/boostPopenHandler.d" -MT"src/boostPopenHandler.d" -o"src/boostPopenHandler.o" "../src/boostPopenHandler.cpp"
In file included from ../src/boostPopenHandler.cpp:4:0:
/usr/include/boost/iostreams/device/file_descriptor.hpp: In instantiation of ‘boost::iostreams::file_descriptor_sink::file_descriptor_sink(const Path&, std::ios_base::openmode) [with Path = char; std::ios_base::openmode = std::_Ios_Openmode]’:
/usr/include/boost/iostreams/stream_buffer.hpp:94:5: required from ‘boost::iostreams::stream_buffer<T, Tr, Alloc, Mode>::stream_buffer(U100&, typename boost::disable_if<boost::is_same<U0, T> >::type*) [with U100 = char; T = boost::iostreams::file_descriptor_sink; Tr = std::char_traits<char>; Alloc = std::allocator<char>; Mode = boost::iostreams::output_seekable; typename boost::disable_if<boost::is_same<U0, T> >::type = void]’
../src/boostPopenHandler.cpp:13:83: required from here
/usr/include/boost/iostreams/device/file_descriptor.hpp:276:36: error: invalid conversion from ‘char’ to ‘const char*’ [-fpermissive]
{ open(detail::path(path), mode); }
^
In file included from /usr/include/boost/iostreams/device/file_descriptor.hpp:26:0,
from ../src/boostPopenHandler.cpp:4:
/usr/include/boost/iostreams/detail/path.hpp:52:5: error: initializing argument 1 of ‘boost::iostreams::detail::path::path(const char*)’ [-fpermissive]
path(const char* p) : narrow_(p), wide_(), is_wide_(false) { }
^
In file included from ../src/boostPopenHandler.cpp:4:0:
/usr/include/boost/iostreams/device/file_descriptor.hpp: In instantiation of ‘boost::iostreams::file_descriptor_source::file_descriptor_source(const Path&, std::ios_base::openmode) [with Path = char; std::ios_base::openmode = std::_Ios_Openmode]’:
/usr/include/boost/iostreams/stream_buffer.hpp:94:5: required from ‘boost::iostreams::stream_buffer<T, Tr, Alloc, Mode>::stream_buffer(U100&, typename boost::disable_if<boost::is_same<U0, T> >::type*) [with U100 = char; T = boost::iostreams::file_descriptor_source; Tr = std::char_traits<char>; Alloc = std::allocator<char>; Mode = boost::iostreams::input_seekable; typename boost::disable_if<boost::is_same<U0, T> >::type = void]’
../src/boostPopenHandler.cpp:26:85: required from here
/usr/include/boost/iostreams/device/file_descriptor.hpp:194:36: error: invalid conversion from ‘char’ to ‘const char*’ [-fpermissive]
{ open(detail::path(path), mode); }
^
In file included from /usr/include/boost/iostreams/device/file_descriptor.hpp:26:0,
from ../src/boostPopenHandler.cpp:4:
/usr/include/boost/iostreams/detail/path.hpp:52:5: error: initializing argument 1 of ‘boost::iostreams::detail::path::path(const char*)’ [-fpermissive]
path(const char* p) : narrow_(p), wide_(), is_wide_(false) { }
^
make: *** [src/boostPopenHandler.o] Error 1
Edit:Following the answer from Selçuk Cihan, I changed the relevant code to:
boost::iostreams::file_descriptor_source fds(fd);
boost::iostreams::stream_buffer<boost::iostreams::file_descriptor_sink>
...
boost::iostreams::file_descriptor_source fds(fd);
boost::iostreams::stream_buffer<boost::iostreams::file_descriptor_source>
But I still get a list of compile errors:
**** Build of configuration Debug for project boostPopenHandler ****
make all
Building file: ../src/boostPopenHandler.cpp
Invoking: GCC C++ Compiler
g++ -I../../emdw/src -I../../patrecII/src -I../../ -O0 -g3 -Wall -c -fmessage-length=0 -std=c++0x -MMD -MP -MF"src/boostPopenHandler.d" -MT"src/boostPopenHandler.d" -o"src/boostPopenHandler.o" "../src/boostPopenHandler.cpp"
In file included from ../src/boostPopenHandler.cpp:4:0:
/usr/include/boost/iostreams/device/file_descriptor.hpp: In instantiation of ‘boost::iostreams::file_descriptor_source::file_descriptor_source(const Path&, std::ios_base::openmode) [with Path = int; std::ios_base::openmode = std::_Ios_Openmode]’:
../src/boostPopenHandler.cpp:13:52: required from here
/usr/include/boost/iostreams/device/file_descriptor.hpp:194:36: error: invalid conversion from ‘int’ to ‘const char*’ [-fpermissive]
{ open(detail::path(path), mode); }
^
In file included from /usr/include/boost/iostreams/device/file_descriptor.hpp:26:0,
from ../src/boostPopenHandler.cpp:4:
/usr/include/boost/iostreams/detail/path.hpp:52:5: error: initializing argument 1 of ‘boost::iostreams::detail::path::path(const char*)’ [-fpermissive]
path(const char* p) : narrow_(p), wide_(), is_wide_(false) { }
^
In file included from ../src/boostPopenHandler.cpp:4:0:
/usr/include/boost/iostreams/device/file_descriptor.hpp: In instantiation of ‘boost::iostreams::file_descriptor_sink::file_descriptor_sink(const Path&, std::ios_base::openmode) [with Path = boost::iostreams::file_descriptor_source; std::ios_base::openmode = std::_Ios_Openmode]’:
/usr/include/boost/iostreams/stream_buffer.hpp:94:5: required from ‘boost::iostreams::stream_buffer<T, Tr, Alloc, Mode>::stream_buffer(U100&, typename boost::disable_if<boost::is_same<U0, T> >::type*) [with U100 = boost::iostreams::file_descriptor_source; T = boost::iostreams::file_descriptor_sink; Tr = std::char_traits<char>; Alloc = std::allocator<char>; Mode = boost::iostreams::output_seekable; typename boost::disable_if<boost::is_same<U0, T> >::type = void]’
../src/boostPopenHandler.cpp:14:84: required from here
/usr/include/boost/iostreams/device/file_descriptor.hpp:276:36: error: no matching function for call to ‘boost::iostreams::detail::path::path(const boost::iostreams::file_descriptor_source&)’
{ open(detail::path(path), mode); }
^
/usr/include/boost/iostreams/device/file_descriptor.hpp:276:36: note: candidates are:
In file included from /usr/include/boost/iostreams/device/file_descriptor.hpp:26:0,
from ../src/boostPopenHandler.cpp:4:
/usr/include/boost/iostreams/detail/path.hpp:138:5: note: boost::iostreams::detail::path::path(const wstring&)
path(const std::wstring&);
^
/usr/include/boost/iostreams/detail/path.hpp:138:5: note: no known conversion for argument 1 from ‘const boost::iostreams::file_descriptor_source’ to ‘const wstring& {aka const std::basic_string<wchar_t>&}’
/usr/include/boost/iostreams/detail/path.hpp:70:5: note: boost::iostreams::detail::path::path(const boost::iostreams::detail::path&)
path(const path& p)
^
/usr/include/boost/iostreams/detail/path.hpp:70:5: note: no known conversion for argument 1 from ‘const boost::iostreams::file_descriptor_source’ to ‘const boost::iostreams::detail::path&’
/usr/include/boost/iostreams/detail/path.hpp:64:14: note: template<class Path> boost::iostreams::detail::path::path(const Path&, typename Path::codecvt_type*)
explicit path(const Path& p, typename Path::codecvt_type* = 0)
^
/usr/include/boost/iostreams/detail/path.hpp:64:14: note: template argument deduction/substitution failed:
/usr/include/boost/iostreams/detail/path.hpp: In substitution of ‘template<class Path> boost::iostreams::detail::path::path(const Path&, typename Path::codecvt_type*) [with Path = boost::iostreams::file_descriptor_source]’:
/usr/include/boost/iostreams/device/file_descriptor.hpp:276:36: required from ‘boost::iostreams::file_descriptor_sink::file_descriptor_sink(const Path&, std::ios_base::openmode) [with Path = boost::iostreams::file_descriptor_source; std::ios_base::openmode = std::_Ios_Openmode]’
/usr/include/boost/iostreams/stream_buffer.hpp:94:5: required from ‘boost::iostreams::stream_buffer<T, Tr, Alloc, Mode>::stream_buffer(U100&, typename boost::disable_if<boost::is_same<U0, T> >::type*) [with U100 = boost::iostreams::file_descriptor_source; T = boost::iostreams::file_descriptor_sink; Tr = std::char_traits<char>; Alloc = std::allocator<char>; Mode = boost::iostreams::output_seekable; typename boost::disable_if<boost::is_same<U0, T> >::type = void]’
../src/boostPopenHandler.cpp:14:84: required from here
/usr/include/boost/iostreams/detail/path.hpp:64:14: error: no type named ‘codecvt_type’ in ‘class boost::iostreams::file_descriptor_source’
/usr/include/boost/iostreams/device/file_descriptor.hpp: In instantiation of ‘boost::iostreams::file_descriptor_sink::file_descriptor_sink(const Path&, std::ios_base::openmode) [with Path = boost::iostreams::file_descriptor_source; std::ios_base::openmode = std::_Ios_Openmode]’:
/usr/include/boost/iostreams/stream_buffer.hpp:94:5: required from ‘boost::iostreams::stream_buffer<T, Tr, Alloc, Mode>::stream_buffer(U100&, typename boost::disable_if<boost::is_same<U0, T> >::type*) [with U100 = boost::iostreams::file_descriptor_source; T = boost::iostreams::file_descriptor_sink; Tr = std::char_traits<char>; Alloc = std::allocator<char>; Mode = boost::iostreams::output_seekable; typename boost::disable_if<boost::is_same<U0, T> >::type = void]’
../src/boostPopenHandler.cpp:14:84: required from here
/usr/include/boost/iostreams/detail/path.hpp:57:14: note: template<class Path> boost::iostreams::detail::path::path(const Path&, typename Path::external_string_type*)
explicit path(const Path& p, typename Path::external_string_type* = 0)
^
/usr/include/boost/iostreams/detail/path.hpp:57:14: note: template argument deduction/substitution failed:
/usr/include/boost/iostreams/detail/path.hpp: In substitution of ‘template<class Path> boost::iostreams::detail::path::path(const Path&, typename Path::external_string_type*) [with Path = boost::iostreams::file_descriptor_source]’:
/usr/include/boost/iostreams/device/file_descriptor.hpp:276:36: required from ‘boost::iostreams::file_descriptor_sink::file_descriptor_sink(const Path&, std::ios_base::openmode) [with Path = boost::iostreams::file_descriptor_source; std::ios_base::openmode = std::_Ios_Openmode]’
/usr/include/boost/iostreams/stream_buffer.hpp:94:5: required from ‘boost::iostreams::stream_buffer<T, Tr, Alloc, Mode>::stream_buffer(U100&, typename boost::disable_if<boost::is_same<U0, T> >::type*) [with U100 = boost::iostreams::file_descriptor_source; T = boost::iostreams::file_descriptor_sink; Tr = std::char_traits<char>; Alloc = std::allocator<char>; Mode = boost::iostreams::output_seekable; typename boost::disable_if<boost::is_same<U0, T> >::type = void]’
../src/boostPopenHandler.cpp:14:84: required from here
/usr/include/boost/iostreams/detail/path.hpp:57:14: error: no type named ‘external_string_type’ in ‘class boost::iostreams::file_descriptor_source’
/usr/include/boost/iostreams/device/file_descriptor.hpp: In instantiation of ‘boost::iostreams::file_descriptor_sink::file_descriptor_sink(const Path&, std::ios_base::openmode) [with Path = boost::iostreams::file_descriptor_source; std::ios_base::openmode = std::_Ios_Openmode]’:
/usr/include/boost/iostreams/stream_buffer.hpp:94:5: required from ‘boost::iostreams::stream_buffer<T, Tr, Alloc, Mode>::stream_buffer(U100&, typename boost::disable_if<boost::is_same<U0, T> >::type*) [with U100 = boost::iostreams::file_descriptor_source; T = boost::iostreams::file_descriptor_sink; Tr = std::char_traits<char>; Alloc = std::allocator<char>; Mode = boost::iostreams::output_seekable; typename boost::disable_if<boost::is_same<U0, T> >::type = void]’
../src/boostPopenHandler.cpp:14:84: required from here
/usr/include/boost/iostreams/detail/path.hpp:52:5: note: boost::iostreams::detail::path::path(const char*)
path(const char* p) : narrow_(p), wide_(), is_wide_(false) { }
^
/usr/include/boost/iostreams/detail/path.hpp:52:5: note: no known conversion for argument 1 from ‘const boost::iostreams::file_descriptor_source’ to ‘const char*’
/usr/include/boost/iostreams/detail/path.hpp:49:5: note: boost::iostreams::detail::path::path(const string&)
path(const std::string& p) : narrow_(p), wide_(), is_wide_(false) { }
^
/usr/include/boost/iostreams/detail/path.hpp:49:5: note: no known conversion for argument 1 from ‘const boost::iostreams::file_descriptor_source’ to ‘const string& {aka const std::basic_string<char>&}’
/usr/include/boost/iostreams/detail/path.hpp:46:5: note: boost::iostreams::detail::path::path()
path() : narrow_(), wide_(), is_wide_(false) { }
^
/usr/include/boost/iostreams/detail/path.hpp:46:5: note: candidate expects 0 arguments, 1 provided
make: *** [src/boostPopenHandler.o] Error 1
Oh, you should be first declaring a file_descriptor_source as in
boost::iostreams::file_descriptor_source fds(fd);
and then comes your stream buffer
boost::iostreams::stream_buffer<boost::iostreams::file_descriptor_source> bis(fds);
Edit:
Sorry for the confusion, that ctor with an int parameter is deprecated and it seems that you do not have that ctor because otherwise your code would compile perfectly. That is why the above code i supplied needs a second mandatory parameter of either boost::iostreams::never_close_handle or boost::iostreams::close_handle
So it should read
boost::iostreams::file_descriptor_source fds(fd, boost::iostreams::close_handle);
otherwise you would still get that error. And same fix goes with the file_descriptor_sink also.
Now as for how you should read the errors:
/usr/include/boost/iostreams/device/file_descriptor.hpp: In
instantiation of
‘boost::iostreams::file_descriptor_source::file_descriptor_source(const
Path&, std::ios_base::openmode) [with Path = char;
std::ios_base::openmode = std::_Ios_Openmode]’:
Says that it tried to instantiate a file_descriptor_source with a template parameter choice of
[with Path = char; std::ios_base::openmode = std::_Ios_Openmode]
Since you only supplied an integer, the compiler tried to match that version of the ctor and failed to make the conversion.
You don't need Boost for this.
wanted to convert a *FILE (such as returned by popen()) to a iostream
Use pstreams instead (disclaimer, I wrote it, if that matters).
Some compilers provide extensions to create a streambuf from a C file without needing Boost, e.g. with GCC:
#include <ext/stdio_filebuf.h>
...
__gnu_cxx::stdio_filebuf<char> fb(fp, std::ios::out);
std::ostream os(&fb);
I have the following unordered_map, that maps a pointer to an object of type Item with a key of type int.
typedef std::unordered_map<int, Item*> ItemList;
ItemList Items;
However, in my addItem method, I receive a strange error at compilation.
void ItemManager::addItem(Item *it) {
int i = it->getItemID();
Items.insert(ItemList::value_type(i, *it));
}
Yields:
item_manager.cc: In member function ‘void ItemManager::addItem(Item*)’:
item_manager.cc:31:51: error: no matching function for call to ‘std::pair<const int, Item*>::pair(int&, Item&)’
item_manager.cc:31:51: note: candidates are:
/usr/include/c++/4.6/bits/stl_pair.h:140:2: note: template<class ... _Args1, class ... _Args2> std::pair::pair(std::piecewise_construct_t, std::tuple<_Args1 ...>, std::tuple<_Args2 ...>)
/usr/include/c++/4.6/bits/stl_pair.h:135:2: note: template<class _U1, class _U2> std::pair::pair(std::pair<_U1, _U2>&&)
/usr/include/c++/4.6/bits/stl_pair.h:131:2: note: template<class _U1, class _U2, class> std::pair::pair(_U1&&, _U2&&)
/usr/include/c++/4.6/bits/stl_pair.h:125:2: note: template<class _U2, class> std::pair::pair(const _T1&, _U2&&)
/usr/include/c++/4.6/bits/stl_pair.h:120:2: note: template<class _U1, class> std::pair::pair(_U1&&, const _T2&)
/usr/include/c++/4.6/bits/stl_pair.h:112:17: note: constexpr std::pair<_T1, _T2>::pair(const std::pair<_T1, _T2>&) [with _T1 = const int, _T2 = Process*, std::pair<_T1, _T2> = std::pair<const int, Process*>]
/usr/include/c++/4.6/bits/stl_pair.h:112:17: note: candidate expects 1 argument, 2 provided
/usr/include/c++/4.6/bits/stl_pair.h:108:21: note: template<class _U1, class _U2> constexpr std::pair::pair(const std::pair<_U1, _U2>&)
/usr/include/c++/4.6/bits/stl_pair.h:103:26: note: constexpr std::pair<_T1, _T2>::pair(const _T1&, const _T2&) [with _T1 = const int, _T2 = Process*]
/usr/include/c++/4.6/bits/stl_pair.h:103:26: note: no known conversion for argument 2 from ‘Process’ to ‘Process* const&’
/usr/include/c++/4.6/bits/stl_pair.h:99:26: note: constexpr std::pair<_T1, _T2>::pair() [with _T1 = const int, _T2 = Process*]
/usr/include/c++/4.6/bits/stl_pair.h:99:26: note: candidate expects 0 arguments, 2 provided
Any ideas what could be causing these errors? I'm new to C++, so I have been working off of examples of unordered_maps I've found around the web. Any help is greatly appreciated. Please and thank you!
The values in your map are of type Item*, so you need to insert Item*, not Item. This line
Items.insert(ItemList::value_type(i, *it));
should be
Items.insert(ItemList::value_type(i, it));
You don't need to dereference the pointer:
void ItemManager::addItem(Item *it) {
int i = it->getItemID();
Items.insert(ItemList::value_type(i, it));
}