boost::cregexp_iterator compliation errors - c++

I'm trying to use boost::cregexp_iterator, as exaplined in http://www.boost.org/doc/libs/1_55_0/libs/regex/doc/html/boost_regex/ref/regex_iterator.html
// Loop through all the patterns
auto sessionReconstructionsEnd = _sessionReconstructions.end();
for (auto sr = _sessionReconstructions.begin(); sr != sessionReconstructionsEnd; ++sr) {
const std::string& pattern = sr->first;
const auto& editors = sr->second;
regex re(pattern);
...
for (auto session = sessions.begin(); session != sessionsEnd; ++session) {
for (size_t chunkNumber = 0; chunkNumber < sessionChunks.size(); ++chunkNumber) {
const auto& chunkData = sessionChunks[chunkNumber].data;
cregex_iterator reIteratorEnd;
cregex_iterator reIterator(
reinterpret_cast<const char*>(chunkData.data()),
reinterpret_cast<const char*>(chunkData.data()) + chunkData.size(),
re); // Here the search is being done...
All the other code is commented out. I get the following error:
^
In file included from /usr/include/boost/regex/v4/regex.hpp:67:0,
from /usr/include/boost/regex.hpp:31,
from LGEJobConfiguration.cpp:4:
/usr/include/boost/regex/v4/basic_regex.hpp: In instantiation of ‘boost::basic_regex<charT, traits>::basic_regex(const boost::basic_regex<charT, traits>&) [with charT = char; traits = boost::regex_traits<char>]’:
/usr/include/boost/regex/v4/regex_iterator.hpp:52:43: required from ‘boost::regex_iterator_implementation<BidirectionalIterator, charT, traits>::regex_iterator_implementation(const regex_type*, BidirectionalIterator, boost::regex_constants::match_flag_type) [with BidirectionalIterator = const char*; charT = char; traits = boost::regex_traits<char>; boost::regex_iterator_implementation<BidirectionalIterator, charT, traits>::regex_type = boost::basic_regex<char, boost::regex_traits<char> >; boost::regex_constants::match_flag_type = boost::regex_constants::_match_flags]’
/usr/include/boost/regex/v4/regex_iterator.hpp:113:46: required from ‘boost::regex_iterator<BidirectionalIterator, charT, traits>::regex_iterator(BidirectionalIterator, BidirectionalIterator, const regex_type&, boost::regex_constants::match_flag_type) [with BidirectionalIterator = const char*; charT = char; traits = boost::regex_traits<char>; boost::regex_iterator<BidirectionalIterator, charT, traits>::regex_type = boost::basic_regex<char, boost::regex_traits<char> >; boost::regex_constants::match_flag_type = boost::regex_constants::_match_flags]’
LGEJobConfiguration.cpp:543:8: required from here
/usr/include/boost/regex/v4/basic_regex.hpp:344:29: error: use of deleted function ‘boost::shared_ptr<boost::re_detail::basic_regex_implementation<char, boost::regex_traits<char> > >::shared_ptr(const boost::shared_ptr<boost::re_detail::basic_regex_implementation<char, boost::regex_traits<char> > >&)’
: m_pimpl(that.m_pimpl) {}
^
In file included from /usr/include/boost/shared_ptr.hpp:17:0,
from /usr/include/boost/regex/v4/regex_workaround.hpp:43,
from /usr/include/boost/regex/v4/regex.hpp:32,
from /usr/include/boost/regex.hpp:31,
from LGEJobConfiguration.cpp:4:
/usr/include/boost/smart_ptr/shared_ptr.hpp:168:25: note: ‘boost::shared_ptr<boost::re_detail::basic_regex_implementation<char, boost::regex_traits<char> > >::shared_ptr(const boost::shared_ptr<boost::re_detail::basic_regex_implementation<char, boost::regex_traits<char> > >&)’ is implicitly declared as deleted because ‘boost::shared_ptr<boost::re_detail::basic_regex_implementation<char, boost::regex_traits<char> > >’ declares a move constructor or move assignment operator
template<class T> class shared_ptr
^
/usr/include/boost/smart_ptr/shared_ptr.hpp: In instantiation of ‘boost::shared_ptr<T>& boost::shared_ptr<T>::operator=(const boost::shared_ptr<T>&) [with T = boost::re_detail::named_subexpressions]’:
/usr/include/boost/regex/v4/match_results.hpp:549:20: required from ‘void boost::match_results<BidiIterator, Allocator>::set_named_subs(boost::shared_ptr<boost::re_detail::named_subexpressions>) [with BidiIterator = const char*; Allocator = std::allocator<boost::sub_match<const char*> >]’
/usr/include/boost/regex/v4/perl_matcher_common.hpp:265:7: required from ‘bool boost::re_detail::perl_matcher<BidiIterator, Allocator, traits>::find_imp() [with BidiIterator = const char*; Allocator = std::allocator<boost::sub_match<const char*> >; traits = boost::regex_traits<char>]’
/usr/include/boost/regex/v4/perl_matcher_common.hpp:230:20: required from ‘bool boost::re_detail::perl_matcher<BidiIterator, Allocator, traits>::find() [with BidiIterator = const char*; Allocator = std::allocator<boost::sub_match<const char*> >; traits = boost::regex_traits<char>]’
/usr/include/boost/regex/v4/regex_search.hpp:56:24: required from ‘bool boost::regex_search(BidiIterator, BidiIterator, boost::match_results<Iterator, Allocator>&, const boost::basic_regex<charT, traits>&, boost::regex_constants::match_flag_type, BidiIterator) [with BidiIterator = const char*; Allocator = std::allocator<boost::sub_match<const char*> >; charT = char; traits = boost::regex_traits<char>; boost::regex_constants::match_flag_type = boost::regex_constants::_match_flags]’
/usr/include/boost/smart_ptr/shared_ptr.hpp:168:25: note: ‘boost::shared_ptr<boost::re_detail::named_subexpressions>::shared_ptr(const boost::shared_ptr<boost::re_detail::named_subexpressions>&)’ is implicitly declared as deleted because ‘boost::shared_ptr<boost::re_detail::named_subexpressions>’ declares a move constructor or move assignment operator
template<class T> class shared_ptr
^
In file included from /usr/include/boost/regex/v4/regex.hpp:82:0,
from /usr/include/boost/regex.hpp:31,
from LGEJobConfiguration.cpp:4:
/usr/include/boost/regex/v4/match_results.hpp: In instantiation of ‘boost::match_results<BidiIterator, Allocator>::match_results(const boost::match_results<BidiIterator, Allocator>&) [with BidiIterator = const char*; Allocator = std::allocator<boost::sub_match<const char*> >]’:
/usr/include/boost/regex/v4/perl_matcher_non_recursive.hpp:134:76: required from ‘boost::re_detail::saved_recursion<Results>::saved_recursion(int, const boost::re_detail::re_syntax_base*, Results*) [with Results = boost::match_results<const char*>]’
/usr/include/boost/regex/v4/perl_matcher_non_recursive.hpp:342:4: required from ‘void boost::re_detail::perl_matcher<BidiIterator, Allocator, traits>::push_recursion(int, const boost::re_detail::re_syntax_base*, boost::re_detail::perl_matcher<BidiIterator, Allocator, traits>::results_type*) [with BidiIterator = const char*; Allocator = std::allocator<boost::sub_match<const char*> >; traits = boost::regex_traits<char>; boost::re_detail::perl_matcher<BidiIterator, Allocator, traits>::results_type = boost::match_results<const char*>]’
/usr/include/boost/regex/v4/perl_matcher_non_recursive.hpp:935:127: required from ‘bool boost::re_detail::perl_matcher<BidiIterator, Allocator, traits>::match_endmark() [with BidiIterator = const char*; Allocator = std::allocator<boost::sub_match<const char*> >; traits = boost::regex_traits<char>]’
/usr/include/boost/regex/v4/perl_matcher_non_recursive.hpp:147:7: required from ‘bool boost::re_detail::perl_matcher<BidiIterator, Allocator, traits>::match_all_states() [with BidiIterator = const char*; Allocator = std::allocator<boost::sub_match<const char*> >; traits = boost::regex_traits<char>]’
/usr/include/boost/regex/v4/perl_matcher_common.hpp:323:21: [ skipping 2 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ]
/usr/include/boost/regex/v4/perl_matcher_common.hpp:230:20: required from ‘bool boost::re_detail::perl_matcher<BidiIterator, Allocator, traits>::find() [with BidiIterator = const char*; Allocator = std::allocator<boost::sub_match<const char*> >; traits = boost::regex_traits<char>]’
/usr/include/boost/regex/v4/regex_search.hpp:56:24: required from ‘bool boost::regex_search(BidiIterator, BidiIterator, boost::match_results<Iterator, Allocator>&, const boost::basic_regex<charT, traits>&, boost::regex_constants::match_flag_type, BidiIterator) [with BidiIterator = const char*; Allocator = std::allocator<boost::sub_match<const char*> >; charT = char; traits = boost::regex_traits<char>; boost::regex_constants::match_flag_type = boost::regex_constants::_match_flags]’
/usr/include/boost/regex/v4/regex_search.hpp:42:55: required from ‘bool boost::regex_search(BidiIterator, BidiIterator, boost::match_results<Iterator, Allocator>&, const boost::basic_regex<charT, traits>&, boost::regex_constants::match_flag_type) [with BidiIterator = const char*; Allocator = std::allocator<boost::sub_match<const char*> >; charT = char; traits = boost::regex_traits<char>; boost::regex_constants::match_flag_type = boost::regex_constants::_match_flags]’
/usr/include/boost/regex/v4/regex_iterator.hpp:56:54: required from ‘bool boost::regex_iterator_implementation<BidirectionalIterator, charT, traits>::init(BidirectionalIterator) [with BidirectionalIterator = const char*; charT = char; traits = boost::regex_traits<char>]’
/usr/include/boost/regex/v4/regex_iterator.hpp:115:10: required from ‘boost::regex_iterator<BidirectionalIterator, charT, traits>::regex_iterator(BidirectionalIterator, BidirectionalIterator, const regex_type&, boost::regex_constants::match_flag_type) [with BidirectionalIterator = const char*; charT = char; traits = boost::regex_traits<char>; boost::regex_iterator<BidirectionalIterator, charT, traits>::regex_type = boost::basic_regex<char, boost::regex_traits<char> >; boost::regex_constants::match_flag_type = boost::regex_constants::_match_flags]’
LGEJobConfiguration.cpp:543:8: required from here
/usr/include/boost/regex/v4/match_results.hpp:81:130: error: use of deleted function ‘boost::shared_ptr<boost::re_detail::named_subexpressions>::shared_ptr(const boost::shared_ptr<boost::re_detail::named_subexpressions>&)’
: m_subs(m.m_subs), m_named_subs(m.m_named_subs), m_last_closed_paren(m.m_last_closed_paren), m_is_singular(m.m_is_singular)
what the problem?
UPDATE: the problem is with the flag --std=c++11 - I'm posting another post for this issue.
UPDATE2: The problem is I was using an old version of boost (1.4.3), moving to lastest solved it

Let me do your work for you show you how I'd analyze this problem:
#include <boost/regex.hpp>
#include <boost/cregex.hpp>
#include <vector>
int main()
{
using namespace boost;
regex re(".*");
const std::vector<char> chunkData;
cregex_iterator reIteratorEnd;
cregex_iterator reIterator(
reinterpret_cast<const char*>(chunkData.data()),
reinterpret_cast<const char*>(chunkData.data()) + chunkData.size(),
re); // Here the search is being done...}
}
This compiles just fine for me. And there's nothing else given in your question that we can actually reproduce.
You can take it from there. See when it starts to fail. 90% of the time, it will then be obvious why it fails. Otherwise, come back with the clearer, better question.
PS.
I'm aware of the fact that this is technically not an answer. I think it's helping nonetheless (and it doesn't quite fit in a comment)
You of course don't need the re-interpret cast here in my SSCCE. I'm assuming your chunkData might be (who knows) actually a std::deque<unsigned char> or similar? In such a case, see whether you should use a static_cast: When should static_cast, dynamic_cast, const_cast and reinterpret_cast be used? and Regular cast vs. static_cast vs. dynamic_cast

Related

Reference to vector element in allocator aware class calls copy constructor

I have a class that contains a vector of vector. It is allocator aware. When trying to call the operator[] to store elements in a reference, Visual Studio 2015 fails to compile, AppleClang (latest) is fine with it.
I am unsure whether this is a bug or not, which compiler is right, or if there is some undefined behaviour somewhere in my code.
Here is a concise example, with everything as simple as possible.
#include <cstdlib>
#include <memory>
#include <new>
#include <vector>
/* Allocator */
template <class T>
struct my_allocator {
typedef T value_type;
my_allocator() = default;
template <class U>
constexpr my_allocator(const my_allocator<U>&) noexcept {
}
T* allocate(std::size_t n) {
if (n > std::size_t(-1) / sizeof(T))
throw std::bad_alloc();
if (auto p = static_cast<T*>(std::malloc(n * sizeof(T))))
return p;
throw std::bad_alloc();
}
void deallocate(T* p, std::size_t) noexcept {
std::free(p);
}
};
template <class T, class U>
bool operator==(const my_allocator<T>&, const my_allocator<U>&) {
return true;
}
template <class T, class U>
bool operator!=(const my_allocator<T>&, const my_allocator<U>&) {
return false;
}
/* Example Element */
struct X {
X() = default;
X(X&&) = default;
X& operator=(X&&) = default;
X(const X&) = delete;
X& operator=(const X&) = delete;
int test = 42;
};
/* Example Container Class */
template <class T, class Allocator = std::allocator<T>>
struct vec_of_vec {
using OuterAlloc = typename std::allocator_traits<
Allocator>::template rebind_alloc<std::vector<T, Allocator>>;
vec_of_vec(const Allocator& alloc = Allocator{})
: data(10, std::vector<T, Allocator>{ alloc },
OuterAlloc{ alloc }) {
for (int i = 0; i < 10; ++i) {
data[i].resize(42);
}
}
std::vector<T, Allocator>& operator[](size_t i) {
return data[i];
}
std::vector<std::vector<T, Allocator>, OuterAlloc> data;
};
/* Trigger Error */
int main(int, char**) {
my_allocator<X> alloc;
vec_of_vec<X, my_allocator<X>> test(alloc);
X& ref_test = test[0][0]; // <-- Error Here!
printf("%d\n", ref_test.test);
return 0;
}
VS tries to use the copy constructor of X.
error C2280: 'X::X(const X &)': attempting to reference a deleted function
function main.cpp(42): note: see declaration of 'X::X'
Is there something I am missing with the use of allocators and allocator_traits?
GCC error sheds light on what's going on, potentially same in VS2015 case.
In file included from memory:65,
from prog.cc:2:
bits/stl_uninitialized.h: In instantiation of '_ForwardIterator std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator, _Allocator&) [with _InputIterator = __gnu_cxx::__normal_iterator<const X*, std::vector<X, my_allocator<X> > >; _ForwardIterator = X*; _Allocator = my_allocator<X>]':
bits/stl_vector.h:454:31: required from 'std::vector<_Tp, _Alloc>::vector(const std::vector<_Tp, _Alloc>&) [with _Tp = X; _Alloc = my_allocator<X>]'
bits/alloc_traits.h:250:4: required from 'static std::_Require<std::__and_<std::__not_<typename std::allocator_traits<_Alloc>::__construct_helper<_Tp, _Args>::type>, std::is_constructible<_Tp, _Args ...> > > std::allocator_traits<_Alloc>::_S_construct(_Alloc&, _Tp*, _Args&& ...) [with _Tp = std::vector<X, my_allocator<X> >; _Args = {const std::vector<X, my_allocator<X> >&}; _Alloc = my_allocator<std::vector<X, my_allocator<X> > >; std::_Require<std::__and_<std::__not_<typename std::allocator_traits<_Alloc>::__construct_helper<_Tp, _Args>::type>, std::is_constructible<_Tp, _Args ...> > > = void]'
bits/alloc_traits.h:344:16: required from 'static decltype (std::allocator_traits<_Alloc>::_S_construct(__a, __p, (forward<_Args>)(std::allocator_traits::construct::__args)...)) std::allocator_traits<_Alloc>::construct(_Alloc&, _Tp*, _Args&& ...) [with _Tp = std::vector<X, my_allocator<X> >; _Args = {const std::vector<X, my_allocator<X> >&}; _Alloc = my_allocator<std::vector<X, my_allocator<X> > >; decltype (std::allocator_traits<_Alloc>::_S_construct(__a, __p, (forward<_Args>)(std::allocator_traits::construct::__args)...)) = void]'
bits/stl_uninitialized.h:351:25: required from '_ForwardIterator std::__uninitialized_fill_n_a(_ForwardIterator, _Size, const _Tp&, _Allocator&) [with _ForwardIterator = std::vector<X, my_allocator<X> >*; _Size = long unsigned int; _Tp = std::vector<X, my_allocator<X> >; _Allocator = my_allocator<std::vector<X, my_allocator<X> > >]'
bits/stl_vector.h:1466:33: required from 'void std::vector<_Tp, _Alloc>::_M_fill_initialize(std::vector<_Tp, _Alloc>::size_type, const value_type&) [with _Tp = std::vector<X, my_allocator<X> >; _Alloc = my_allocator<std::vector<X, my_allocator<X> > >; std::vector<_Tp, _Alloc>::size_type = long unsigned int; std::vector<_Tp, _Alloc>::value_type = std::vector<X, my_allocator<X> >]'
bits/stl_vector.h:421:9: required from 'std::vector<_Tp, _Alloc>::vector(std::vector<_Tp, _Alloc>::size_type, const value_type&, const allocator_type&) [with _Tp = std::vector<X, my_allocator<X> >; _Alloc = my_allocator<std::vector<X, my_allocator<X> > >; std::vector<_Tp, _Alloc>::size_type = long unsigned int; std::vector<_Tp, _Alloc>::value_type = std::vector<X, my_allocator<X> >; std::vector<_Tp, _Alloc>::allocator_type = my_allocator<std::vector<X, my_allocator<X> > >]'
prog.cc:59:42: required from 'vec_of_vec<T, Allocator>::vec_of_vec(const Allocator&) [with T = X; Allocator = my_allocator<X>]'
prog.cc:76:46: required from here
bits/stl_uninitialized.h:275:25: error: no matching function for call to '__gnu_cxx::__alloc_traits<my_allocator<X>, X>::construct(my_allocator<X>&, X*, const X&)'
__traits::construct(__alloc, std::__addressof(*__cur), *__first);```
Wandbox
if we go from bottom to top we see:
vec_of_vec constructor
filling vector<vector> by 10 copies of empty inner vector
construction of copies
Despite of the fact that inner vector is empty, its copy constructor requires that the type it contains is copy-constructible.
P.S.
I don't know how clang overcomes this. Potentially it recognises that vector<vector> if filled with default value (if constructor with passed allocator instance still qualifies as default) and so instead of copying uses default construction
EDIT:
To fix the error replace
vec_of_vec(const Allocator& alloc = Allocator{})
: data(10, std::vector<T, Allocator>{ alloc },
OuterAlloc{ alloc }) {
for (int i = 0; i < 10; ++i) {
data[i].resize(42);
}
}
by
vec_of_vec(const Allocator& alloc = Allocator{})
{
data.resize(10); // here we don't `fill` it by copies but default-construct 10 instances
for (int i = 0; i < 10; ++i) {
data[i].resize(42);
}
}
or version for stateful allocator:
vec_of_vec(const Allocator& alloc = Allocator{}):
data(OuterAlloc(alloc))
{
for (int i = 0; i < 10; ++i) {
data.emplace_back(alloc);
data.back().resize(42);
}
}

Compile error with boost::spirit::x3

I tried to compile example file
with gcc 5.3.1 (5.3.1 20160406 (Red Hat 5.3.1-6) (GCC)), boost 1.61.0.
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/home/x3.hpp>
#include <iostream>
// Presented are various ways to attach semantic actions
// * Using plain function pointer
// * Using simple function object
namespace client
{
namespace x3 = boost::spirit::x3;
using x3::_attr;
struct print_action
{
template <typename Context>
void operator()(Context const& ctx) const
{
std::cout << _attr(ctx) << std::endl;
}
};
}
int main()
{
using boost::spirit::x3::int_;
using boost::spirit::x3::parse;
using client::print_action;
{ // example using function object
char const *first = "{43}", *last = first + std::strlen(first);
parse(first, last, '{' >> int_[print_action()] >> '}');
}
{ // example using C++14 lambda
char const *first = "{44}", *last = first + std::strlen(first);
auto f = [](auto& ctx){ std::cout << _attr(ctx) << std::endl; };
parse(first, last, '{' >> int_[f] >> '}');
}
return 0;
}
The compile command is:g++ test.cpp -std=c++1y (I just renamed the file.)
I got the following error:
test.cpp: In instantiation of ‘main()::<lambda(auto:1&)> [with auto:1 = const boost::spirit::x3::context<boost::spirit::x3::attr_context_tag, int, boost::spirit::x3::context<boost::spirit::x3::where_context_tag, boost::iterator_range<const char*>, boost::spirit::x3::context<boost::spirit::x3::rule_val_context_tag, const boost::spirit::x3::unused_type, boost::spirit::x3::context<boost::spirit::x3::parse_pass_context_tag, bool, boost::spirit::x3::unused_type> > > >]’:
/usr/local/include/boost/spirit/home/x3/support/utility/is_callable.hpp:20:35: required from ‘struct boost::spirit::x3::is_callable<main()::<lambda(auto:1&)>(const boost::spirit::x3::context<boost::spirit::x3::attr_context_tag, int, boost::spirit::x3::context<boost::spirit::x3::where_context_tag, boost::iterator_range<const char*>, boost::spirit::x3::context<boost::spirit::x3::rule_val_context_tag, const boost::spirit::x3::unused_type, boost::spirit::x3::context<boost::spirit::x3::parse_pass_context_tag, bool, boost::spirit::x3::unused_type> > > >&)>’
/usr/local/include/boost/spirit/home/x3/core/call.hpp:72:28: required from ‘auto boost::spirit::x3::call(F, Iterator&, const Iterator&, const Context&, RuleContext&, Attribute&) [with F = main()::<lambda(auto:1&)>; Iterator = const char*; Context = boost::spirit::x3::context<boost::spirit::x3::parse_pass_context_tag, bool, boost::spirit::x3::unused_type>; RuleContext = const boost::spirit::x3::unused_type; Attribute = int]’
/usr/local/include/boost/spirit/home/x3/core/action.hpp:45:17: required from ‘bool boost::spirit::x3::action<Subject, Action>::call_action(Iterator&, const Iterator&, const Context&, RuleContext&, Attribute&) const [with Iterator = const char*; Context = boost::spirit::x3::unused_type; RuleContext = const boost::spirit::x3::unused_type; Attribute = int; Subject = boost::spirit::x3::int_parser<int>; Action = main()::<lambda(auto:1&)>]’
/usr/local/include/boost/spirit/home/x3/core/action.hpp:57:32: required from ‘bool boost::spirit::x3::action<Subject, Action>::parse_main(Iterator&, const Iterator&, const Context&, RuleContext&, Attribute&) const [with Iterator = const char*; Context = boost::spirit::x3::unused_type; RuleContext = const boost::spirit::x3::unused_type; Attribute = int; Subject = boost::spirit::x3::int_parser<int>; Action = main()::<lambda(auto:1&)>]’
/usr/local/include/boost/spirit/home/x3/operator/sequence.hpp:32:17: recursively required from ‘bool boost::spirit::x3::sequence<Left, Right>::parse(Iterator&, const Iterator&, const Context&, RContext&, boost::spirit::x3::unused_type) const [with Iterator = const char*; Context = boost::spirit::x3::unused_type; RContext = const boost::spirit::x3::unused_type; Left = boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type>; Right = boost::spirit::x3::action<boost::spirit::x3::int_parser<int>, main()::<lambda(auto:1&)> >]’
/usr/local/include/boost/spirit/home/x3/operator/sequence.hpp:32:17: required from ‘bool boost::spirit::x3::sequence<Left, Right>::parse(Iterator&, const Iterator&, const Context&, RContext&, boost::spirit::x3::unused_type) const [with Iterator = const char*; Context = boost::spirit::x3::unused_type; RContext = const boost::spirit::x3::unused_type; Left = boost::spirit::x3::sequence<boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type>, boost::spirit::x3::action<boost::spirit::x3::int_parser<int>, main()::<lambda(auto:1&)> > >; Right = boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type>]’
/usr/local/include/boost/spirit/home/x3/core/parse.hpp:35:68: required from ‘bool boost::spirit::x3::parse_main(Iterator&, Iterator, const Parser&, Attribute&) [with Iterator = const char*; Parser = boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type>, boost::spirit::x3::action<boost::spirit::x3::int_parser<int>, main()::<lambda(auto:1&)> > >, boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type> >; Attribute = const boost::spirit::x3::unused_type]’
/usr/local/include/boost/spirit/home/x3/core/parse.hpp:71:26: required from ‘bool boost::spirit::x3::parse(Iterator&, Iterator, const Parser&) [with Iterator = const char*; Parser = boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type>, boost::spirit::x3::action<boost::spirit::x3::int_parser<int>, main()::<lambda(auto:1&)> > >, boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type> >]’
test.cpp:47:49: required from here
test.cpp:46:51: 错误:use of ‘template<class Context> decltype(auto) boost::spirit::x3::_attr(const Context&)’ before deduction of ‘auto’
auto f = [](auto& ctx){ std::cout << _attr(ctx) << std::endl; };
^
test.cpp:46:51: 错误:use of ‘decltype(auto) boost::spirit::x3::_attr(const Context&) [with Context = boost::spirit::x3::context<boost::spirit::x3::attr_context_tag, int, boost::spirit::x3::context<boost::spirit::x3::where_context_tag, boost::iterator_range<const char*>, boost::spirit::x3::context<boost::spirit::x3::rule_val_context_tag, const boost::spirit::x3::unused_type, boost::spirit::x3::context<boost::spirit::x3::parse_pass_context_tag, bool, boost::spirit::x3::unused_type> > > >]’ before deduction of ‘auto’
In file included from /usr/local/include/boost/spirit/home/x3/core/action.hpp:13:0,
from /usr/local/include/boost/spirit/home/x3/core.hpp:14,
from /usr/local/include/boost/spirit/home/x3.hpp:20,
from test.cpp:8:
/usr/local/include/boost/spirit/home/x3/core/call.hpp: In instantiation of ‘auto boost::spirit::x3::call(F, Iterator&, const Iterator&, const Context&, RuleContext&, Attribute&) [with F = main()::<lambda(auto:1&)>; Iterator = const char*; Context = boost::spirit::x3::context<boost::spirit::x3::parse_pass_context_tag, bool, boost::spirit::x3::unused_type>; RuleContext = const boost::spirit::x3::unused_type; Attribute = int]’:
/usr/local/include/boost/spirit/home/x3/core/action.hpp:45:17: required from ‘bool boost::spirit::x3::action<Subject, Action>::call_action(Iterator&, const Iterator&, const Context&, RuleContext&, Attribute&) const [with Iterator = const char*; Context = boost::spirit::x3::unused_type; RuleContext = const boost::spirit::x3::unused_type; Attribute = int; Subject = boost::spirit::x3::int_parser<int>; Action = main()::<lambda(auto:1&)>]’
/usr/local/include/boost/spirit/home/x3/core/action.hpp:57:32: required from ‘bool boost::spirit::x3::action<Subject, Action>::parse_main(Iterator&, const Iterator&, const Context&, RuleContext&, Attribute&) const [with Iterator = const char*; Context = boost::spirit::x3::unused_type; RuleContext = const boost::spirit::x3::unused_type; Attribute = int; Subject = boost::spirit::x3::int_parser<int>; Action = main()::<lambda(auto:1&)>]’
/usr/local/include/boost/spirit/home/x3/operator/sequence.hpp:32:17: recursively required from ‘bool boost::spirit::x3::sequence<Left, Right>::parse(Iterator&, const Iterator&, const Context&, RContext&, boost::spirit::x3::unused_type) const [with Iterator = const char*; Context = boost::spirit::x3::unused_type; RContext = const boost::spirit::x3::unused_type; Left = boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type>; Right = boost::spirit::x3::action<boost::spirit::x3::int_parser<int>, main()::<lambda(auto:1&)> >]’
/usr/local/include/boost/spirit/home/x3/operator/sequence.hpp:32:17: required from ‘bool boost::spirit::x3::sequence<Left, Right>::parse(Iterator&, const Iterator&, const Context&, RContext&, boost::spirit::x3::unused_type) const [with Iterator = const char*; Context = boost::spirit::x3::unused_type; RContext = const boost::spirit::x3::unused_type; Left = boost::spirit::x3::sequence<boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type>, boost::spirit::x3::action<boost::spirit::x3::int_parser<int>, main()::<lambda(auto:1&)> > >; Right = boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type>]’
/usr/local/include/boost/spirit/home/x3/core/parse.hpp:35:68: required from ‘bool boost::spirit::x3::parse_main(Iterator&, Iterator, const Parser&, Attribute&) [with Iterator = const char*; Parser = boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type>, boost::spirit::x3::action<boost::spirit::x3::int_parser<int>, main()::<lambda(auto:1&)> > >, boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type> >; Attribute = const boost::spirit::x3::unused_type]’
/usr/local/include/boost/spirit/home/x3/core/parse.hpp:71:26: required from ‘bool boost::spirit::x3::parse(Iterator&, Iterator, const Parser&) [with Iterator = const char*; Parser = boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type>, boost::spirit::x3::action<boost::spirit::x3::int_parser<int>, main()::<lambda(auto:1&)> > >, boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type> >]’
test.cpp:47:49: required from here
/usr/local/include/boost/spirit/home/x3/core/call.hpp:72:28: 错误:use of ‘auto boost::spirit::x3::detail::call(F, const Context&, mpl_::true_) [with F = main()::<lambda(auto:1&)>; Context = boost::spirit::x3::context<boost::spirit::x3::attr_context_tag, int, boost::spirit::x3::context<boost::spirit::x3::where_context_tag, boost::iterator_range<const char*>, boost::spirit::x3::context<boost::spirit::x3::rule_val_context_tag, const boost::spirit::x3::unused_type, boost::spirit::x3::context<boost::spirit::x3::parse_pass_context_tag, bool, boost::spirit::x3::unused_type> > > >; mpl_::true_ = mpl_::bool_<true>]’ before deduction of ‘auto’
return detail::call(f, attr_context, is_callable<F(decltype(attr_context) const&)>());
^
I wonder what leads to this error?
P.S: In the file, 错误 means Error.
Note It looks like you linked the wrong sample file. My answer responds to the code shown in the error message instead.
I can't reproduce the problem, but I remember seeing something similar once.
It seems GCC sometimes has trouble doing ADL for a polymorphic lambda parameter type.
The way I got around it was to disable ADL there:
auto f = [](auto& ctx){ std::cout << x3::_attr(ctx) << std::endl; };
or:
auto f = [](auto& ctx){ std::cout << (_attr)(ctx) << std::endl; };

copying between instances of different variant template classes

Why does one variant assignment compile while the other does not? The template instances do not share any types and char could be converted to int, say. What is boost::variant trying to do, that it cannot do in the case of the first assignment and that it can do in the case of the second assignment? Error is below.
#include <string>
#include "boost/variant.hpp"
int main()
{
boost::variant<char> v1;
boost::variant<std::string, int, double> v2;
v1 = v2; // compile error
v2 = v1; // compiles fine
return 0;
}
In file included from /usr/include/boost/variant.hpp:17:0,
from v.cpp:3:
/usr/include/boost/variant/variant.hpp: In instantiation of 'int boost::variant<T0, TN>::convert_copy_into::internal_visit(T&, int) const [with T = const std::basic_string<char>; T0_ = char; TN = {}]':
/usr/include/boost/variant/detail/visitation_impl.hpp:113:9: required from 'typename Visitor::result_type boost::detail::variant::visitation_impl_invoke_impl(int, Visitor&, VoidPtrCV, T*, mpl_::true_) [with Visitor = boost::variant<char>::convert_copy_into; VoidPtrCV = const void*; T = std::basic_string<char>; typename Visitor::result_type = int; mpl_::true_ = mpl_::bool_<true>]'
/usr/include/boost/variant/detail/visitation_impl.hpp:156:9: required from 'typename Visitor::result_type boost::detail::variant::visitation_impl_invoke(int, Visitor&, VoidPtrCV, T*, NoBackupFlag, int) [with Visitor = boost::variant<char>::convert_copy_into; VoidPtrCV = const void*; T = std::basic_string<char>; NoBackupFlag = boost::variant<std::basic_string<char>, int, double>::has_fallback_type_; typename Visitor::result_type = int]'
/usr/include/boost/variant/detail/visitation_impl.hpp:237:5: required from 'typename Visitor::result_type boost::detail::variant::visitation_impl(int, int, Visitor&, VoidPtrCV, mpl_::false_, NoBackupFlag, Which*, step0*) [with Which = mpl_::int_<0>; step0 = boost::detail::variant::visitation_impl_step<boost::mpl::l_iter<boost::mpl::l_item<mpl_::long_<3l>, std::basic_string<char>, boost::mpl::l_item<mpl_::long_<2l>, int, boost::mpl::l_item<mpl_::long_<1l>, double, boost::mpl::l_end> > > >, boost::mpl::l_iter<boost::mpl::l_end> >; Visitor = boost::variant<char>::convert_copy_into; VoidPtrCV = const void*; NoBackupFlag = boost::variant<std::basic_string<char>, int, double>::has_fallback_type_; typename Visitor::result_type = int; mpl_::false_ = mpl_::bool_<false>]'
/usr/include/boost/variant/variant.hpp:2245:13: required from 'static typename Visitor::result_type boost::variant<T0, TN>::internal_apply_visitor_impl(int, int, Visitor&, VoidPtrCV) [with Visitor = boost::variant<char>::convert_copy_into; VoidPtrCV = const void*; T0_ = std::basic_string<char>; TN = {int, double}; typename Visitor::result_type = int]'
/usr/include/boost/variant/variant.hpp:2267:13: [ skipping 2 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ]
/usr/include/boost/variant/variant.hpp:1581:13: required from 'void boost::variant<T0, TN>::convert_construct_variant(Variant&) [with Variant = const boost::variant<std::basic_string<char>, int, double>; T0_ = char; TN = {}]'
/usr/include/boost/variant/variant.hpp:1628:42: required from 'void boost::variant<T0, TN>::convert_construct(const boost::variant<U0, UN ...>&, long int) [with U0 = std::basic_string<char>; UN = {int, double}; T0_ = char; TN = {}]'
/usr/include/boost/variant/variant.hpp:1649:38: required from 'boost::variant<T0, TN>::variant(const T&) [with T = boost::variant<std::basic_string<char>, int, double>; T0_ = char; TN = {}]'
/usr/include/boost/variant/variant.hpp:2059:29: required from 'void boost::variant<T0, TN>::assign(const T&) [with T = boost::variant<std::basic_string<char>, int, double>; T0_ = char; TN = {}]'
/usr/include/boost/variant/variant.hpp:2099:19: required from 'boost::variant<T0, TN>& boost::variant<T0, TN>::operator=(const T&) [with T = boost::variant<std::basic_string<char>, int, double>; T0_ = char; TN = {}]'
v.cpp:10:6: required from here
/usr/include/boost/variant/variant.hpp:1366:61: error: no matching function for call to 'boost::variant<char>::initializer::initialize(void* const&, const std::basic_string<char>&)'
return initializer::initialize(storage_, operand);
^
/usr/include/boost/variant/variant.hpp:1366:61: note: candidates are:
In file included from /usr/include/boost/variant/variant.hpp:32:0,
from /usr/include/boost/variant.hpp:17,
from v.cpp:3:
/usr/include/boost/variant/detail/initializer.hpp:104:24: note: static int boost::detail::variant::make_initializer_node::apply<BaseIndexPair, Iterator>::initializer_node::initialize(void*, boost::detail::variant::make_initializer_node::apply<BaseIndexPair, Iterator>::initializer_node::param_T) [with BaseIndexPair = boost::mpl::pair<boost::detail::variant::initializer_root, mpl_::int_<0> >; Iterator = boost::mpl::l_iter<boost::mpl::list1<char> >; boost::detail::variant::make_initializer_node::apply<BaseIndexPair, Iterator>::initializer_node::param_T = const char&]
static int initialize(void* dest, param_T operand)
^
/usr/include/boost/variant/detail/initializer.hpp:104:24: note: no known conversion for argument 2 from 'const std::basic_string<char>' to 'boost::detail::variant::make_initializer_node::apply<boost::mpl::pair<boost::detail::variant::initializer_root, mpl_::int_<0> >, boost::mpl::l_iter<boost::mpl::list1<char> > >::initializer_node::param_T {aka const char&}'
/usr/include/boost/variant/detail/initializer.hpp:115:24: note: static int boost::detail::variant::make_initializer_node::apply<BaseIndexPair, Iterator>::initializer_node::initialize(void*, boost::detail::variant::make_initializer_node::apply<BaseIndexPair, Iterator>::initializer_node::param2_T) [with BaseIndexPair = boost::mpl::pair<boost::detail::variant::initializer_root, mpl_::int_<0> >; Iterator = boost::mpl::l_iter<boost::mpl::list1<char> >; boost::detail::variant::make_initializer_node::apply<BaseIndexPair, Iterator>::initializer_node::param2_T = char&&]
static int initialize(void* dest, param2_T operand)
^
/usr/include/boost/variant/detail/initializer.hpp:115:24: note: no known conversion for argument 2 from 'const std::basic_string<char>' to 'boost::detail::variant::make_initializer_node::apply<boost::mpl::pair<boost::detail::variant::initializer_root, mpl_::int_<0> >, boost::mpl::l_iter<boost::mpl::list1<char> > >::initializer_node::param2_T {aka char&&}'
/usr/include/boost/variant/detail/initializer.hpp:149:17: note: static void boost::detail::variant::initializer_root::initialize()
static void initialize();
^
/usr/include/boost/variant/detail/initializer.hpp:149:17: note: candidate expects 0 arguments, 2 provided
A char definitely can be stored in an int but the converse is not always true. Therefore the one that fails to compile would be unsafe at runtime, so you're probably better off with it failing. Cast the int to a char if you must.

HippoMocks - mocking methods with std::vector fail to compile

While trying out HippoMocks (Cygwin, GCC 4.5.3, CppUnit) to mock an interface, one of the methods is causing compilation to fail. Further triage shows that only mocking methods with std::vector as arguments would fail.
e.g.
m_Mocks.ExpectCall(m_EmpSvcMock.get(), IEmployeeServiceProxy::GetEmployees); // compile error!
m_Mocks.ExpectCall(m_EmpSvcMock.get(), IEmployeeServiceProxy::AddEmployee); // compile OK!
where
class IEmployeeServiceProxy
{
public:
virtual ~IEmployeeServiceProxy() { }
virtual void AddEmployee(const Employee&) = 0;
virtual void GetEmployees(std::vector<Employee>&) = 0;
};
struct Employee
{
boost::uuids::uuid Id;
std::string Name;
};
Compiler error:
/usr/lib/gcc/i686-pc-cygwin/4.5.3/include/c++/bits/stream_iterator.h: In member function ‘std::ostream_iterator<_Tp, _CharT, _Traits>& std::ostream_iterator<_Tp, _CharT, _Traits>::operator=(const _Tp&) [with _Tp = EmployeeServiceLib::Employee, _CharT = char, _Traits = std::char_traits<char>, std::ostream_iterator<_Tp, _CharT, _Traits> = std::ostream_iterator<EmployeeServiceLib::Employee, char, std::char_traits<char> >]’:
In file included from /usr/lib/gcc/i686-pc-cygwin/4.5.3/include/c++/iterator:67:0,
from /usr/include/boost/uuid/string_generator.hpp:14,
from /usr/include/boost/uuid/uuid_generators.hpp:15,
from tests/../../RcfTestShared/IEmployeeService.hpp:7,
from tests/../IEmployeeServiceProxy.h:11,
from tests/ClientTest.h:13,
from tests/ClientTest.cpp:8:
/usr/lib/gcc/i686-pc-cygwin/4.5.3/include/c++/bits/stl_algobase.h:349:8: instantiated from ‘static _OI std::__copy_move<false, false, std::random_access_iterator_tag>::__copy_m(_II, _II, _OI) [with _II = const EmployeeServiceLib::Employee*, _OI = std::ostream_iterator<EmployeeServiceLib::Employee, char, std::char_traits<char> >]’
/usr/lib/gcc/i686-pc-cygwin/4.5.3/include/c++/bits/stl_algobase.h:404:70: instantiated from ‘_OI std::__copy_move_a(_II, _II, _OI) [with bool _IsMove = false, _II = const EmployeeServiceLib::Employee*, _OI = std::ostream_iterator<EmployeeServiceLib::Employee, char, std::char_traits<char> >]’
/usr/lib/gcc/i686-pc-cygwin/4.5.3/include/c++/bits/stl_algobase.h:442:39: instantiated from ‘_OI std::__copy_move_a2(_II, _II, _OI) [with bool _IsMove = false, _II = __gnu_cxx::__normal_iterator<const EmployeeServiceLib::Employee*, std::vector<EmployeeServiceLib::Employee> >, _OI = std::ostream_iterator<EmployeeServiceLib::Employee, char, std::char_traits<char> >]’
/usr/lib/gcc/i686-pc-cygwin/4.5.3/include/c++/bits/stl_algobase.h:474:18: instantiated from ‘_OI std::copy(_II, _II, _OI) [with _II = __gnu_cxx::__normal_iterator<const EmployeeServiceLib::Employee*, std::vector<EmployeeServiceLib::Employee> >, _OI = std::ostream_iterator<EmployeeServiceLib::Employee, char, std::char_traits<char> >]’
../../RCF/RCF-1.3.1/include/RCF/Tools.hpp:116:9: instantiated from ‘std::ostream& std::operator<<(std::ostream&, const std::vector<_RealType>&) [with T = EmployeeServiceLib::Employee, std::ostream = std::basic_ostream<char>]’
../../hippomocks/HippoMocks/hippomocks.h:94:5: instantiated from ‘static void printArg<T>::print(std::ostream&, T, bool) [with T = std::vector<EmployeeServiceLib::Employee>&, std::ostream = std::basic_ostream<char>]’
../../hippomocks/HippoMocks/hippomocks.h:170:5: instantiated from ‘void ref_tuple<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P>::printTo(std::ostream&) const [with A = std::vector<EmployeeServiceLib::Employee>&, B = NullType, C = NullType, D = NullType, E = NullType, F = NullType, G = NullType, H = NullType, I = NullType, J = NullType, K = NullType, L = NullType, M = NullType, N = NullType, O = NullType, P = NullType, std::ostream = std::basic_ostream<char>]’
tests/ClientTest.cpp:47:1: instantiated from here
/usr/lib/gcc/i686-pc-cygwin/4.5.3/include/c++/bits/stream_iterator.h:196:2: error: cannot bind ‘std::ostream_iterator<EmployeeServiceLib::Employee, char, std::char_traits<char> >::ostream_type’ lvalue to ‘std::basic_ostream<char>&&’
/usr/lib/gcc/i686-pc-cygwin/4.5.3/include/c++/ostream:579:5: error: initializing argument 1 of ‘std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = char, _Traits = std::char_traits<char>, _Tp = EmployeeServiceLib::Employee]’
Possibly it's complaining that you don't have operator<< defined for Employee, but I'm not certain. I think you've missed the last line of your error messages? In any case I would read the documentation and see what requirements they have for the class being tested.
Requiring you to define operator== and operator<< and maybe others is pretty standard for a unit testing framework. If you think about it a unit testing framework is going to need to compare objects of the types you are testing and maybe going to try and output those objects when things go wrong.

Higher order function « filter » in C++

I wanted to write a higher order function filter with C++. The code I have come up with so far is as follows:
#include <iostream>
#include <string>
#include <functional>
#include <algorithm>
#include <vector>
#include <list>
#include <iterator>
using namespace std;
bool isOdd(int const i) {
return i % 2 != 0;
}
template <
template <class, class> class Container,
class Predicate,
class Allocator,
class A
>
Container<A, Allocator> filter(Container<A, Allocator> const & container, Predicate const & pred) {
Container<A, Allocator> filtered(container);
container.erase(remove_if(filtered.begin(), filtered.end(), pred), filtered.end());
return filtered;
}
int main() {
int const a[] = {23, 12, 78, 21, 97, 64};
vector<int const> const v(a, a + 6);
vector<int const> const filtered = filter(v, isOdd);
copy(filtered.begin(), filtered.end(), ostream_iterator<int const>(cout, " "));
}
However on compiling this code, I get the following error messages that I am unable to understand and hence get rid of:
/usr/include/c++/4.3/ext/new_allocator.h: In instantiation of ‘__gnu_cxx::new_allocator<const int>’:
/usr/include/c++/4.3/bits/allocator.h:84: instantiated from ‘std::allocator<const int>’
/usr/include/c++/4.3/bits/stl_vector.h:75: instantiated from ‘std::_Vector_base<const int, std::allocator<const int> >’
/usr/include/c++/4.3/bits/stl_vector.h:176: instantiated from ‘std::vector<const int, std::allocator<const int> >’
Filter.cpp:29: instantiated from here
/usr/include/c++/4.3/ext/new_allocator.h:82: error: ‘const _Tp* __gnu_cxx::new_allocator<_Tp>::address(const _Tp&) const [with _Tp = const int]’ cannot be overloaded
/usr/include/c++/4.3/ext/new_allocator.h:79: error: with ‘_Tp* __gnu_cxx::new_allocator<_Tp>::address(_Tp&) const [with _Tp = const int]’
Filter.cpp: In function ‘Container<A, Allocator> filter(const Container<A, Allocator>&, const Predicate&) [with Container = std::vector, Predicate = bool ()(int), Allocator = std::allocator<const int>, A = const int]’:
Filter.cpp:30: instantiated from here
Filter.cpp:23: error: passing ‘const std::vector<const int, std::allocator<const int> >’ as ‘this’ argument of ‘__gnu_cxx::__normal_iterator<typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer, std::vector<_Tp, _Alloc> > std::vector<_Tp, _Alloc>::erase(__gnu_cxx::__normal_iterator<typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer, std::vector<_Tp, _Alloc> >, __gnu_cxx::__normal_iterator<typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer, std::vector<_Tp, _Alloc> >) [with _Tp = const int, _Alloc = std::allocator<const int>]’ discards qualifiers
/usr/include/c++/4.3/bits/stl_algo.h: In function ‘_FIter std::remove_if(_FIter, _FIter, _Predicate) [with _FIter = __gnu_cxx::__normal_iterator<const int*, std::vector<const int, std::allocator<const int> > >, _Predicate = bool (*)(int)]’:
Filter.cpp:23: instantiated from ‘Container<A, Allocator> filter(const Container<A, Allocator>&, const Predicate&) [with Container = std::vector, Predicate = bool ()(int), Allocator = std::allocator<const int>, A = const int]’
Filter.cpp:30: instantiated from here
/usr/include/c++/4.3/bits/stl_algo.h:821: error: assignment of read-only location ‘__result.__gnu_cxx::__normal_iterator<_Iterator, _Container>::operator* [with _Iterator = const int*, _Container = std::vector<const int, std::allocator<const int> >]()’
/usr/include/c++/4.3/ext/new_allocator.h: In member function ‘void __gnu_cxx::new_allocator<_Tp>::deallocate(_Tp*, size_t) [with _Tp = const int]’:
/usr/include/c++/4.3/bits/stl_vector.h:150: instantiated from ‘void std::_Vector_base<_Tp, _Alloc>::_M_deallocate(_Tp*, size_t) [with _Tp = const int, _Alloc = std::allocator<const int>]’
/usr/include/c++/4.3/bits/stl_vector.h:136: instantiated from ‘std::_Vector_base<_Tp, _Alloc>::~_Vector_base() [with _Tp = const int, _Alloc = std::allocator<const int>]’
/usr/include/c++/4.3/bits/stl_vector.h:286: instantiated from ‘std::vector<_Tp, _Alloc>::vector(_InputIterator, _InputIterator, const _Alloc&) [with _InputIterator = const int*, _Tp = const int, _Alloc = std::allocator<const int>]’
Filter.cpp:29: instantiated from here
/usr/include/c++/4.3/ext/new_allocator.h:98: error: invalid conversion from ‘const void*’ to ‘void*’
/usr/include/c++/4.3/ext/new_allocator.h:98: error: initializing argument 1 of ‘void operator delete(void*)’
/usr/include/c++/4.3/bits/stl_algobase.h: In function ‘_OI std::__copy_move_a(_II, _II, _OI) [with bool _IsMove = false, _II = const int*, _OI = const int*]’:
/usr/include/c++/4.3/bits/stl_algobase.h:435: instantiated from ‘_OI std::__copy_move_a2(_II, _II, _OI) [with bool _IsMove = false, _II = __gnu_cxx::__normal_iterator<const int*, std::vector<const int, std::allocator<const int> > >, _OI = __gnu_cxx::__normal_iterator<const int*, std::vector<const int, std::allocator<const int> > >]’
/usr/include/c++/4.3/bits/stl_algobase.h:466: instantiated from ‘_OI std::copy(_II, _II, _OI) [with _II = __gnu_cxx::__normal_iterator<const int*, std::vector<const int, std::allocator<const int> > >, _OI = __gnu_cxx::__normal_iterator<const int*, std::vector<const int, std::allocator<const int> > >]’
/usr/include/c++/4.3/bits/vector.tcc:136: instantiated from ‘__gnu_cxx::__normal_iterator<typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer, std::vector<_Tp, _Alloc> > std::vector<_Tp, _Alloc>::erase(__gnu_cxx::__normal_iterator<typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer, std::vector<_Tp, _Alloc> >, __gnu_cxx::__normal_iterator<typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer, std::vector<_Tp, _Alloc> >) [with _Tp = const int, _Alloc = std::allocator<const int>]’
Filter.cpp:23: instantiated from ‘Container<A, Allocator> filter(const Container<A, Allocator>&, const Predicate&) [with Container = std::vector, Predicate = bool ()(int), Allocator = std::allocator<const int>, A = const int]’
Filter.cpp:30: instantiated from here
/usr/include/c++/4.3/bits/stl_algobase.h:396: error: no matching function for call to ‘std::__copy_move<false, true, std::random_access_iterator_tag>::__copy_m(const int*&, const int*&, const int*&)’
Please tell me what I am doing wrong here and what is the correct way to achieve the kind of higher order polymorphism I want.
Thanks.
EDIT:
Thank you, everyone. Here's the new code I got after applying your suggestions (and it works now, yay!)
#include <iostream>
#include <string>
#include <functional>
#include <algorithm>
#include <vector>
#include <list>
#include <iterator>
using namespace std;
bool isOdd(int const i) {
return i % 2 != 0;
}
template <
template <typename, typename> class Container,
typename Predicate,
typename Allocator,
typename A
>
Container<A, Allocator> filter(Container<A, Allocator> const & container, Predicate const & pred) {
Container<A, Allocator> filtered(container);
filtered.erase(remove_if(filtered.begin(), filtered.end(), pred), filtered.end());
return filtered;
}
int main() {
int a[] = {23, 12, 78, 21, 97, 64};
vector<int> v(a, a + 6);
vector<int> filtered = filter(v, isOdd);
copy(filtered.begin(), filtered.end(), ostream_iterator<int>(cout, " "));
}
Why is your Container parametrized at all?
template <typename C, typename P>
C filter(C const & container, P pred) {
C filtered(container);
filtered.erase(remove_if(filtered.begin(), filtered.end(), pred), filtered.end());
return filtered;
}
Works just as well. Notice that I passed P by value rather than by const reference, as advised by Meyers in Effective C++ (iterators and functors should be passed by value).
what about remove_copy_if instead ? (with isEven()). It's already built for you.
The error is not in filter, but in:
int main() {
int const a[] = {23, 12, 78, 21, 97, 64};
vector<int const> const v(a, a + 6);
}
You can't have a vector of const stuff. Remove the inner const:
int main() {
int const a[] = {23, 12, 78, 21, 97, 64};
vector<int> const v(a, a + 6);
}
(And of course, filtered.erase, not container.erase.)
container is a const-reference. You can't call erase() on it. You probably mean to call
filtered.erase(remove_if(filtered.begin(), filtered.end(), pred), filtered.end());