Using boost::function and boost::bind - c++

I have the following code trying to pass non-static member functions as a replacement idea to old c code where it requires function pointer. It is not compiling. Could you help? Something must be obvious and I am new to this. Thanks in advance. -- Jinping
#include <iostream>
#include <boost/function.hpp>
#include <boost/function_equal.hpp>
#include <boost/bind.hpp>
using namespace boost;
using namespace std;
double addTest( boost::function<double (double)> f, double a, double x )
{
double a1 = f(a);
double a2= a1+x;
return a2;
}
double squareIt (double x) {
return x*x;
}
class X {
public:
X(double x0, double x1){ x=x0+x1; }
double plusIt(double t) { return x+t; }
private:
double x;
};
int main (int argc, char** argv)
{
boost::function<double (double)> f;
f = &squareIt;
double result = addTest(f, 10, 5); //OK
cout << "result = " << result << endl;
X newx(10, 15);
//f=boost::bind(&X::plusIt, &newx); // does not complie
double res2 = addTest(boost::bind(&X::plusIt, &newx), 10, 5); // does not compile
cout << "result2 = " << res2 << endl;
return 0;
}
// compile error:
g++ -Wall -g -O0 -I/meth_mount/utility_sys/boost_1_42_0/ -I/usr/include -I/meth_mount/utility_sys/gsl-1.15/ -I/home/ayuan/work/ird_lib/core_lib/alib/intrface/build/alib/clib/linux -DUNIX -DSET_ENVIRONMENT -DOPTION_RESET -c ./../src/BindTest.cpp
/meth_mount/utility_sys/boost_1_42_0/boost/function/function_template.hpp: In static member function ‘static R boost::detail::function::function_obj_invoker1::invoke(boost::detail::function::function_buffer&, T0) [with FunctionObj = boost::_bi::bind_t, boost::_bi::list1 > >, R = double, T0 = double]’:
/meth_mount/utility_sys/boost_1_42_0/boost/function/function_template.hpp:913: instantiated from ‘void boost::function1::assign_to(Functor) [with Functor = boost::_bi::bind_t, boost::_bi::list1 > >, R = double, T0 = double]’
/meth_mount/utility_sys/boost_1_42_0/boost/function/function_template.hpp:722: instantiated from ‘boost::function1::function1(Functor, typename boost::enable_if_c::value>::value, int>::type) [with Functor = boost::_bi::bind_t, boost::_bi::list1 > >, R = double, T0 = double]’
/meth_mount/utility_sys/boost_1_42_0/boost/function/function_template.hpp:1064: instantiated from ‘boost::function::function(Functor, typename boost::enable_if_c::value>::value, int>::type) [with Functor = boost::_bi::bind_t, boost::_bi::list1 > >, R = double, T0 = double]’
./../src/BindTest.cpp:46: instantiated from here
/meth_mount/utility_sys/boost_1_42_0/boost/function/function_template.hpp:132: error: cannot convert ‘double ()(double)’ to ‘double’ in return
/meth_mount/utility_sys/boost_1_42_0/boost/bind/mem_fn.hpp: In member function ‘R& boost::_mfi::dm::operator()(T) const [with R = double ()(double), T = X]’:
/meth_mount/utility_sys/boost_1_42_0/boost/bind/bind.hpp:243: instantiated from ‘R boost::_bi::list1::operator()(boost::_bi::type, F&, A&, long int) [with R = double (&)(double), F = boost::_mfi::dm, A = boost::_bi::list1, A1 = boost::_bi::value]’
/meth_mount/utility_sys/boost_1_42_0/boost/bind/bind_template.hpp:32: instantiated from ‘typename boost::_bi::result_traits::type boost::_bi::bind_t::operator()(A1&) [with A1 = double, R = double (&)(double), F = boost::_mfi::dm, L = boost::_bi::list1 >]’
/meth_mount/utility_sys/boost_1_42_0/boost/function/function_template.hpp:132: instantiated from ‘static R boost::detail::function::function_obj_invoker1::invoke(boost::detail::function::function_buffer&, T0) [with FunctionObj = boost::_bi::bind_t, boost::_bi::list1 > >, R = double, T0 = double]’
/meth_mount/utility_sys/boost_1_42_0/boost/function/function_template.hpp:913: instantiated from ‘void boost::function1::assign_to(Functor) [with Functor = boost::_bi::bind_t, boost::_bi::list1 > >, R = double, T0 = double]’
/meth_mount/utility_sys/boost_1_42_0/boost/function/function_template.hpp:722: instantiated from ‘boost::function1::function1(Functor, typename boost::enable_if_c::value>::value, int>::type) [with Functor = boost::_bi::bind_t, boost::_bi::list1 > >, R = double, T0 = double]’
/meth_mount/utility_sys/boost_1_42_0/boost/function/function_template.hpp:1064: instantiated from ‘boost::function::function(Functor, typename boost::enable_if_c::value>::value, int>::type) [with Functor = boost::_bi::bind_t, boost::_bi::list1 > >, R = double, T0 = double]’
./../src/BindTest.cpp:46: instantiated from here
/meth_mount/utility_sys/boost_1_42_0/boost/bind/mem_fn.hpp:342: error: invalid use of non-static member function
make: *** [../bin/BindTest.o] Error 1

You are missing _1 which is required because X::plusIt is an unary function (not counting this). The correct code is
double res2 = addTest(boost::bind(&X::plusIt, &newx, _1), 10, 5);
See also Using bind with pointers to members.

Related

Can not compile merge sort tree structure?

I was trying to implement merge sort tree structure but whenever i
try to merge child vector to parent vector i get compilation error . I
am stuck here .
class merge_sort_tree {
vector<int>input;
vector<vector<int> >tr;
int n;
public:
merge_tree(vector<int >p) {
n = p.size();
input = p;
tr.resize(5 * n);
}
void build(int root, int l, int r) {
if (l == r)
{
tr[root] = {input[l]};
}
int m = l + (r - l) / 2;
build(2 * root, l, m);
build(2 * root + 1, m + 1, r);
//temporary vector for merging child vectors
vector<int>tmp(tr[2 * root].size() + tr[2 * root + 1].size());
// merging child vector and storing result in tmp
merge(tr[2 * root].begin(), tr[2 * root].end(),
tr[2 * root + 1].begin(), tr[2 * root + 1].end(),
tmp.begin(), tmp.end() );
tr[root]=tmp;
}
};
In file included from c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_algobase.h:71:0,
from c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\char_traits.h:39,
from c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\ios:40,
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\mingw32\bits\stdc++.h:52,
from C:\Users\Ayuu\Desktop\codes\test3.cc:1:
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\predefined_ops.h: In instantiation of 'constexpr bool __gnu_cxx::__ops::_Iter_comp_iter<_Compare>::operator()(_Iterator1, _Iterator2) [with _Iterator1 = __gnu_cxx::__normal_iterator >; _Iterator2 = __gnu_cxx::__normal_iterator >; _Compare = __gnu_cxx::__normal_iterator >]':
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_algo.h:4751:14: required from '_OutputIterator std::__merge(_InputIterator1, _InputIterator1, _InputIterator2, _InputIterator2, _OutputIterator, _Compare) [with _InputIterator1 = __gnu_cxx::__normal_iterator >; _InputIterator2 = __gnu_cxx::__normal_iterator >; _OutputIterator = __gnu_cxx::__normal_iterator >; _Compare = __gnu_cxx::__ops::_Iter_comp_iter<__gnu_cxx::__normal_iterator > >]'
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_algo.h:4858:37: required from '_OIter std::merge(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare) [with _IIter1 = __gnu_cxx::__normal_iterator >; _IIter2 = __gnu_cxx::__normal_iterator >; _OIter = __gnu_cxx::__normal_iterator >; _Compare = __gnu_cxx::__normal_iterator >]'
C:\Users\Ayuu\Desktop\codes\test3.cc:43:38: required from here
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\predefined_ops.h:123:18: error: no match for call to '(__gnu_cxx::__normal_iterator >) (int&, int&)'
{ return bool(_M_comp(*__it1, *__it2)); }
Look at this line, it expected one iterator, you gave 2
error: no match for call to '(__gnu_cxx::__normal_iterator >) (int&, int&)' { return bool(_M_comp(*__it1, *__it2)); }
Remove tmp.end() from your merge function. It requires 5 arguments not 6.
merge(tr[2 * root].begin(), tr[2 * root].end(),
tr[2 * root + 1].begin(), tr[2 * root + 1].end(),
tmp.begin());
This should work.

Boost coroutine won't compile because of ambiguous call to callcc

I'm trying to use coroutines in a C++ project at work. However, it will not compile because of an ambiguous use of callcc(). I have tried specifying allocators in the coroutine constructor, but that doesn't seem to make a speck of difference.
After stripping down the code to its barest essentials I ended up reproducing the problem with something very similar to the fibbonacci examples from the boost documentation.
#include <iostream>
#include <boost/coroutine2/all.hpp>
/*
c++ -std=c++11 -o corofib corofib.cpp
*/
typedef boost::coroutines2::coroutine<unsigned long> coro_t;
coro_t::pull_type generator(
[](coro_t::push_type& sink) {
unsigned long first = 1L;
unsigned long second = 1L;
unsigned long answer;
sink(first);
sink(second);
while(1) {
answer = first + second;
first = second;
second = answer;
sink(answer);
};
}
);
int main(int argc, char* argv[]) {
generator();
std::cout << generator.get() << std::endl;
generator();
std::cout << generator.get() << std::endl;
generator();
std::cout << generator.get() << std::endl;
generator();
std::cout << generator.get() << std::endl;
}
I am using:
Boost 1.64
gcc version 4.9.2
Linux delegato 3.16.0-4-amd64 #1 SMP
Debian 3.16.39-1+deb8u2 (2017-03-07) x86_64 GNU/Linux
Here's the error messages I'm getting. I've removed the "required from" notices in an attempt to shorten this post:
lear#delegato:~/lamu$ c++ -std=c++14 -o corofib corofib.cpp
In file included from /usr/local/include/boost/coroutine2/detail/coroutine.hpp:48:0,
from /usr/local/include/boost/coroutine2/coroutine.hpp:15,
from /usr/local/include/boost/coroutine2/all.hpp:10,
from corofib.cpp:2:
/usr/local/include/boost/coroutine2/detail/pull_control_block_cc.ipp: In instantiation of ‘boost::coroutines2::detail::pull_coroutine<T>::control_block::control_block(boost::context::preallocated, StackAllocator, Fn&&) [with StackAllocator = boost::context::basic_fixedsize_stack<boost::context::stack_traits>; Fn = <lambda(boost::coroutines2::coroutine<long unsigned int>::push_type&)>; T = long unsigned int]’:
/usr/local/include/boost/coroutine2/detail/pull_control_block_cc.ipp:105:14: error: call of overloaded ‘callcc(const std::allocator_arg_t&, boost::context::preallocated&, boost::context::basic_fixedsize_stack<boost::context::stack_traits>&, boost::coroutines2::detail::pull_coroutine<T>::control_block::control_block(boost::context::preallocated, StackAllocator, Fn&&) [with StackAllocator = boost::context::basic_fixedsize_stack<boost::context::stack_traits>; Fn = <lambda(boost::coroutines2::coroutine<long unsigned int>::push_type&)>; T = long unsigned int]::<lambda(boost::context::continuation&&)>)’ is ambiguous
});
^
/usr/local/include/boost/coroutine2/detail/pull_control_block_cc.ipp:105:14: note: candidates are:
In file included from /usr/local/include/boost/coroutine2/detail/pull_control_block_cc.hpp:14:0,
from /usr/local/include/boost/coroutine2/detail/coroutine.hpp:37,
from /usr/local/include/boost/coroutine2/coroutine.hpp:15,
from /usr/local/include/boost/coroutine2/all.hpp:10,
from corofib.cpp:2:
/usr/local/include/boost/context/continuation.hpp:469:1: note: boost::context::continuation boost::context::callcc(std::allocator_arg_t, StackAlloc, Fn&&, Arg ...) [with StackAlloc = boost::context::preallocated; Fn = boost::context::basic_fixedsize_stack<boost::context::stack_traits>&; Arg = {boost::coroutines2::detail::pull_coroutine<T>::control_block::control_block(boost::context::preallocated, StackAllocator, Fn&&) [with StackAllocator = boost::context::basic_fixedsize_stack<boost::context::stack_traits>; Fn = <lambda(boost::coroutines2::coroutine<long unsigned int>::push_type&)>; T = long unsigned int]::<lambda(boost::context::continuation&&)>}]
callcc( std::allocator_arg_t, StackAlloc salloc, Fn && fn, Arg ... arg) {
^
/usr/local/include/boost/context/continuation.hpp:483:1: note: boost::context::continuation boost::context::callcc(std::allocator_arg_t, boost::context::preallocated, StackAlloc, Fn&&, Arg ...) [with StackAlloc = boost::context::basic_fixedsize_stack<boost::context::stack_traits>; Fn = boost::coroutines2::detail::pull_coroutine<T>::control_block::control_block(boost::context::preallocated, StackAllocator, Fn&&) [with StackAllocator = boost::context::basic_fixedsize_stack<boost::context::stack_traits>; Fn = <lambda(boost::coroutines2::coroutine<long unsigned int>::push_type&)>; T = long unsigned int]::<lambda(boost::context::continuation&&)>; Arg = {}]
callcc( std::allocator_arg_t, preallocated palloc, StackAlloc salloc, Fn && fn, Arg ... arg) {
^
/usr/local/include/boost/context/continuation.hpp:514:1: note: boost::context::continuation boost::context::callcc(std::allocator_arg_t, boost::context::preallocated, StackAlloc, Fn&&) [with StackAlloc = boost::context::basic_fixedsize_stack<boost::context::stack_traits>; Fn = boost::coroutines2::detail::pull_coroutine<T>::control_block::control_block(boost::context::preallocated, StackAllocator, Fn&&) [with StackAllocator = boost::context::basic_fixedsize_stack<boost::context::stack_traits>; Fn = <lambda(boost::coroutines2::coroutine<long unsigned int>::push_type&)>; T = long unsigned int]::<lambda(boost::context::continuation&&)>]
callcc( std::allocator_arg_t, preallocated palloc, StackAlloc salloc, Fn && fn) {
^
/usr/local/include/boost/context/continuation.hpp:457:1: note: boost::context::continuation boost::context::callcc(Fn&&, Arg ...) [with Fn = const std::allocator_arg_t&; Arg = {boost::context::preallocated, boost::context::basic_fixedsize_stack<boost::context::stack_traits>, boost::coroutines2::detail::pull_coroutine<T>::control_block::control_block(boost::context::preallocated, StackAllocator, Fn&&) [with StackAllocator = boost::context::basic_fixedsize_stack<boost::context::stack_traits>; Fn = <lambda(boost::coroutines2::coroutine<long unsigned int>::push_type&)>; T = long unsigned int]::<lambda(boost::context::continuation&&)>}; <template-parameter-1-3> = void]
callcc( Fn && fn, Arg ... arg) {
I think the code is basically sound: I just need to dis-ambiguate this somehow.
I could say something about how easy this is to do in python, but it might incite laughter.
This is a bug in Boost.Context, which was reported and fixed upstream. You can find a patch that is specifically targeted for Boost 1.64 here.

Compiling error when insert pair into set [duplicate]

This question already has answers here:
problems with c++ set container
(2 answers)
Closed 6 years ago.
I can't understand why g++ returns error like this:
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_pair.h: In function 鈥榖ool std::operator<(const std::pair<_T1, _T2>&, const std::pair<_T1, _T2>&) [with _T1 = int, _T2 = stop]鈥
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_function.h:227: instantiated from 鈥榖ool std::less<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = std::pair<int, stop>]鈥
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_tree.h:921: instantiated from 鈥榮td::pair<typename std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator, bool> std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::insert_unique(const _Val&) [with _Key = std::pair<int, stop>, _Val = std::pair<int, stop>, _KeyOfValue = std::_Identity<std::pair<int, stop> >, _Compare = std::less<std::pair<int, stop> >, _Alloc = std::allocator<std::pair<int, stop> >]鈥
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_set.h:321: instantiated from 鈥榮td::pair<typename std::_Rb_tree<_Key, _Key, std::_Identity<_Key>, _Compare, typename _Alloc::rebind<_Key>::other>::const_iterator, bool> std::set<_Key, _Compare, _Alloc>::insert(const _Key&) [with _Key = std::pair<int, stop>, _Compare = std::less<std::pair<int, stop> >, _Alloc = std::allocator<std::pair<int, stop> >]鈥
newGraph.cpp:48: instantiated from here
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_pair.h:104: error: no match for 鈥榦perator<鈥in 鈥榑_x->std::pair<int, stop>::second < __y->std::pair<int, stop>::second鈥
Here is my code:
#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <set>
#include <utility> // for pair
#include <algorithm>
#include <iterator>
const int max_weight = INT_MAX;
struct stop {
std::string name_stop;
int id_stop;
bool operator !=(const stop &rhs) const
{
return ((id_stop != rhs.id_stop) || (name_stop != rhs.name_stop));
}
};
struct neighbor {
stop target;
int weight;
neighbor(stop arg_target, int arg_weight) : target(arg_target), weight(arg_weight) { }
};
std::list<stop> dijkstraComputeAndGetShortestPaths(stop src,
stop dst,
std::vector< std::vector<neighbor> > &adj_list,
std::vector<int> &min_distance,
std::vector<stop> &previous)
{
stop fake_stop;
fake_stop.id_stop = INT_MAX;
fake_stop.name_stop = "Null";
std::list<stop> path;
int n = adj_list.size();
min_distance.clear();
min_distance.resize(n, max_weight);
min_distance[src.id_stop] = 0;
previous.clear();
previous.resize(n, fake_stop);
std::set< std::pair< int, stop > > vertex_queue;
vertex_queue.insert(std::make_pair(min_distance[src.id_stop], src));
while (!vertex_queue.empty())
{
int dist = vertex_queue.begin()->first;
stop u = vertex_queue.begin()->second;
vertex_queue.erase(vertex_queue.begin());
// Visit each edge exiting u
const std::vector<neighbor> &neighbors = adj_list[u.id_stop];
for(std::vector<neighbor>::const_iterator neighbor_iter = neighbors.begin();
neighbor_iter != neighbors.end();
neighbor_iter++)
{
stop v = neighbor_iter->target;
int weight = neighbor_iter->weight;
int distance_through_u = dist + weight;
if (distance_through_u < min_distance[v.id_stop]) {
vertex_queue.erase(std::make_pair(min_distance[v.id_stop], v));
min_distance[v.id_stop] = distance_through_u;
previous[v.id_stop] = u;
vertex_queue.insert(std::make_pair(min_distance[v.id_stop], v));
}
}
if(u.id_stop == dst.id_stop)
{
std::cout << "Find : ";
for ( ; dst != fake_stop; dst = previous[dst.id_stop])
{
path.push_front(dst);
}
return path;
}
}
}
int main()
{
std::vector< std::vector<neighbor> > adj_list(9);
stop stop_s;
stop_s.id_stop = 1001;
stop_s.name_stop = "A";
stop stop_x;
stop_x.id_stop = 1002;
stop_x.name_stop = "B";
adj_list[stop_s.id_stop].push_back(neighbor(stop_x, 5));
stop_s.id_stop = 1003;
stop_s.name_stop = "C";
adj_list[stop_x.id_stop].push_back(neighbor(stop_s, 15));
stop_x.id_stop = 1004;
stop_x.name_stop = "D";
adj_list[stop_s.id_stop].push_back(neighbor(stop_x, 20));
stop_s.id_stop = 1001;
stop_s.name_stop = "A";
std::vector<int> min_distance;
std::vector<stop> previous;
std::list<stop> path = dijkstraComputeAndGetShortestPaths(stop_s, stop_x, adj_list, min_distance, previous);
std::cout << "Distance from 1001 to 1004: " << min_distance[stop_x.id_stop] << std::endl;
//std::cout << "Path : ";
#if 0
for (int index = 0; index < path.size(); index++)
{
auto path_front = path.begin();
std::advance(path_front, index);
std::cout << path_front->id_stop << " ";
}
std::cout << std::endl;
#endif
return 0;
}
std::set require you to specify an operator < for the type it holds or you can supply your own comparison functor as a template parameter. Since stop does not have an operator < the operator < from std::pair is not compileable since it relies on using the operator < of the types it holds.. You either need to supply your own comparison functor or define an operator < for stop.

Spirit karma grammar issue when one rule uses BOOST_FUSION_ADAPT_STRUCT

I am trying to create a Spirit Karma grammar that is composed of several rules. This grammar is intended to create a string of the format "(0, 1, 2, 3), (4, 5, 6, 7), (8, 9, 10, 11)". The rule to print out each individual struct that I call RowData uses BOOST_FUSION_ADAPT_STRUCT to print out all of the fields of that struct. If the grammar only includes that rule, the grammar works fine. However, I am using this struct as the value of a std::map. The key in an integer but I do not care about that value and want to drop it. I have created rules to parse the std::map but the rule that handles the std::pair fails to compile for a BOOST_SPIRIT_ASSERT_MATCH. I have created a small bit of code that generates this issue. The line is pairRule = bs::karma::omit << rowDataRule; If anybody has an idea what the issue is or how I could do this differently, I would appreciate the help.
Edit: I am using gcc 4.8.3 on OpenSUSE 13.2 but get the same error with gcc 4.8.2 on Ubuntu 14.04 LTS.
main.cpp
#include <iostream>
#include <map>
#include <boost/cstdint.hpp>
#include <boost/fusion/adapted/struct/adapt_struct.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/make_tuple.hpp>
#include <boost/fusion/include/std_pair.hpp>
#include <boost/spirit/include/karma.hpp>
namespace bs = boost::spirit;
struct RowData
{
RowData() :
field0(0),
field1(0),
field2(0),
field3(0)
{
}
boost::uint64_t field0;
boost::uint64_t field1;
boost::uint64_t field2;
boost::uint64_t field3;
};
BOOST_FUSION_ADAPT_STRUCT(
RowData,
(boost::uint64_t, field0)
(boost::uint64_t, field1)
(boost::uint64_t, field2)
(boost::uint64_t, field3)
)
template <typename OutputIterator>
struct RowDataGrammar :
bs::karma::grammar< OutputIterator, std::map<boost::uint64_t, RowData>() >
{
RowDataGrammar() : RowDataGrammar::base_type(allRowsRule)
{
rowDataRule =
bs::karma::lit("(") <<
bs::karma::ulong_ <<
bs::karma::lit(", ") <<
bs::karma::ulong_ <<
bs::karma::lit(", ") <<
bs::karma::ulong_ <<
bs::karma::lit(", ") <<
bs::karma::ulong_ <<
bs::karma::lit(")");
// I only want the value from the map. The key is dropped.
pairRule = bs::karma::omit << rowDataRule;
allRowsRule = pairRule % ", ";
}
private:
bs::karma::rule< OutputIterator, RowData() > rowDataRule;
bs::karma::rule< OutputIterator, std::pair<boost::uint64_t, RowData>() > pairRule;
bs::karma::rule< OutputIterator, std::map<boost::uint64_t, RowData>() > allRowsRule;
};
int main(int argc, char** argv)
{
std::map<boost::uint64_t, RowData> rowMap;
RowData rowData;
rowData.field0 = 0;
rowData.field1 = 1;
rowData.field2 = 2;
rowData.field3 = 3;
rowMap.insert(std::make_pair(10, rowData));
rowData.field0 = 6;
rowData.field1 = 7;
rowData.field2 = 8;
rowData.field3 = 9;
rowMap.insert(std::make_pair(20, rowData));
std::string generatedString;
std::back_insert_iterator<std::string> sink(generatedString);
RowDataGrammar< std::back_insert_iterator<std::string> > grammar;
bs::karma::generate(sink, grammar, rowMap);
std::cout << "output :" << generatedString << std::endl;
}
Error message:
In file included from /usr/include/boost/fusion/support/tag_of.hpp:16:0,
from /usr/include/boost/fusion/support/category_of.hpp:11,
from /usr/include/boost/fusion/adapted/struct/detail/extension.hpp:13,
from /usr/include/boost/fusion/adapted/struct/adapt_struct.hpp:19,
from karmaTest.cpp:5:
/usr/include/boost/spirit/home/karma/nonterminal/rule.hpp: In instantiation of ‘static void boost::spirit::karma::rule<OutputIterator, T1, T2, T3, T4>::define(boost::spirit::karma::rule<OutputIterator, T1, T2, T3, T4>&, const Expr&, mpl_::false_) [with Auto = mpl_::bool_<false>; Expr = boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_left, boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::omit>, 0l>&, boost::spirit::karma::rule<std::back_insert_iterator<std::basic_string<char> >, RowData(), boost::spirit::unused_type, boost::spirit::unused_type, boost::spirit::unused_type>&>, 2l>; OutputIterator = std::back_insert_iterator<std::basic_string<char> >; T1 = std::pair<long unsigned int, RowData>(); T2 = boost::spirit::unused_type; T3 = boost::spirit::unused_type; T4 = boost::spirit::unused_type; mpl_::false_ = mpl_::bool_<false>]’:
/usr/include/boost/spirit/home/karma/nonterminal/rule.hpp:229:19: required from ‘boost::spirit::karma::rule<OutputIterator, T1, T2, T3, T4>& boost::spirit::karma::rule<OutputIterator, T1, T2, T3, T4>::operator=(const Expr&) [with Expr = boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_left, boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::omit>, 0l>&, boost::spirit::karma::rule<std::back_insert_iterator<std::basic_string<char> >, RowData(), boost::spirit::unused_type, boost::spirit::unused_type, boost::spirit::unused_type>&>, 2l>; OutputIterator = std::back_insert_iterator<std::basic_string<char> >; T1 = std::pair<long unsigned int, RowData>(); T2 = boost::spirit::unused_type; T3 = boost::spirit::unused_type; T4 = boost::spirit::unused_type]’
karmaTest.cpp:54:18: required from ‘RowDataGrammar<OutputIterator>::RowDataGrammar() [with OutputIterator = std::back_insert_iterator<std::basic_string<char> >]’
karmaTest.cpp:84:62: required from here
/usr/include/boost/spirit/home/karma/nonterminal/rule.hpp:185:13: error: no matching function for call to ‘assertion_failed(mpl_::failed************ (boost::spirit::karma::rule<OutputIterator, T1, T2, T3, T4>::define(boost::spirit::karma::rule<OutputIterator, T1, T2, T3, T4>&, const Expr&, mpl_::false_) [with Auto = mpl_::bool_<false>; Expr = boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_left, boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::omit>, 0l>&, boost::spirit::karma::rule<std::back_insert_iterator<std::basic_string<char> >, RowData(), boost::spirit::unused_type, boost::spirit::unused_type, boost::spirit::unused_type>&>, 2l>; OutputIterator = std::back_insert_iterator<std::basic_string<char> >; T1 = std::pair<long unsigned int, RowData>(); T2 = boost::spirit::unused_type; T3 = boost::spirit::unused_type; T4 = boost::spirit::unused_type; mpl_::false_ = mpl_::bool_<false>]::error_invalid_expression::************)(boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_left, boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::omit>, 0l>&, boost::spirit::karma::rule<std::back_insert_iterator<std::basic_string<char> >, RowData(), boost::spirit::unused_type, boost::spirit::unused_type, boost::spirit::unused_type>&>, 2l>))’
BOOST_SPIRIT_ASSERT_MATCH(karma::domain, Expr);
^
/usr/include/boost/spirit/home/karma/nonterminal/rule.hpp:185:13: note: candidate is:
/usr/include/boost/mpl/assert.hpp:82:5: note: template<bool C> int mpl_::assertion_failed(typename mpl_::assert<C>::type)
int assertion_failed( typename assert<C>::type );
^
/usr/include/boost/mpl/assert.hpp:82:5: note: template argument deduction/substitution failed:
/usr/include/boost/spirit/home/karma/nonterminal/rule.hpp:185:13: note: cannot convert ‘boost::spirit::karma::rule<OutputIterator, T1, T2, T3, T4>::define(boost::spirit::karma::rule<OutputIterator, T1, T2, T3, T4>&, const Expr&, mpl_::false_)::error_invalid_expression185::assert_arg<mpl_::bool_<false>, boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_left, boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::omit>, 0l>&, boost::spirit::karma::rule<std::back_insert_iterator<std::basic_string<char> >, RowData(), boost::spirit::unused_type, boost::spirit::unused_type, boost::spirit::unused_type>&>, 2l> >()’ (type ‘mpl_::failed************ (boost::spirit::karma::rule<OutputIterator, T1, T2, T3, T4>::define(boost::spirit::karma::rule<OutputIterator, T1, T2, T3, T4>&, const Expr&, mpl_::false_) [with Auto = mpl_::bool_<false>; Expr = boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_left, boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::omit>, 0l>&, boost::spirit::karma::rule<std::back_insert_iterator<std::basic_string<char> >, RowData(), boost::spirit::unused_type, boost::spirit::unused_type, boost::spirit::unused_type>&>, 2l>; OutputIterator = std::back_insert_iterator<std::basic_string<char> >; T1 = std::pair<long unsigned int, RowData>(); T2 = boost::spirit::unused_type; T3 = boost::spirit::unused_type; T4 = boost::spirit::unused_type; mpl_::false_ = mpl_::bool_<false>]::error_invalid_expression::************)(boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_left, boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::omit>, 0l>&, boost::spirit::karma::rule<std::back_insert_iterator<std::basic_string<char> >, RowData(), boost::spirit::unused_type, boost::spirit::unused_type, boost::spirit::unused_type>&>, 2l>)’) to type ‘mpl_::assert<false>::type {aka mpl_::assert<false>}’
BOOST_SPIRIT_ASSERT_MATCH(karma::domain, Expr);
As cv_and_he said, I was using omit incorrectly. An old coworker I reached out to told me the same. The corrected code is below.
main.cpp
#include <iostream>
#include <map>
#include <boost/cstdint.hpp>
#include <boost/fusion/adapted/struct/adapt_struct.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/make_tuple.hpp>
#include <boost/fusion/include/std_pair.hpp>
#include <boost/spirit/include/karma.hpp>
namespace bs = boost::spirit;
struct RowData
{
RowData() :
field0(0),
field1(0),
field2(0),
field3(0)
{
}
boost::uint64_t field0;
boost::uint64_t field1;
boost::uint64_t field2;
boost::uint64_t field3;
};
BOOST_FUSION_ADAPT_STRUCT(
RowData,
(boost::uint64_t, field0)
(boost::uint64_t, field1)
(boost::uint64_t, field2)
(boost::uint64_t, field3)
)
template <typename OutputIterator>
struct RowDataGrammar :
bs::karma::grammar< OutputIterator, std::map<boost::uint64_t, RowData>() >
{
RowDataGrammar() : RowDataGrammar::base_type(allRowsRule)
{
rowDataRule =
bs::karma::lit("(") <<
bs::karma::ulong_ <<
bs::karma::lit(", ") <<
bs::karma::ulong_ <<
bs::karma::lit(", ") <<
bs::karma::ulong_ <<
bs::karma::lit(", ") <<
bs::karma::ulong_ <<
bs::karma::lit(")");
// I only want the value from the map. The key is dropped.
pairRule = bs::karma::omit[bs::karma::ulong_] << rowDataRule;
allRowsRule = pairRule % ", ";
}
private:
bs::karma::rule< OutputIterator, RowData() > rowDataRule;
bs::karma::rule< OutputIterator, std::pair<boost::uint64_t, RowData>() > pairRule;
bs::karma::rule< OutputIterator, std::map<boost::uint64_t, RowData>() > allRowsRule;
};
int main(int argc, char** argv)
{
std::map<boost::uint64_t, RowData> rowMap;
RowData rowData;
rowData.field0 = 0;
rowData.field1 = 1;
rowData.field2 = 2;
rowData.field3 = 3;
rowMap.insert(std::make_pair(10, rowData));
rowData.field0 = 6;
rowData.field1 = 7;
rowData.field2 = 8;
rowData.field3 = 9;
rowMap.insert(std::make_pair(20, rowData));
std::string generatedString;
std::back_insert_iterator<std::string> sink(generatedString);
RowDataGrammar< std::back_insert_iterator<std::string> > grammar;
bs::karma::generate(sink, grammar, rowMap);
std::cout << "output :" << generatedString << std::endl;
}

a generic function example using output iterator not working

I have the following template function:
template<class In, class Out>
Out copy(In begin, In end, Out dest)
{
while(begin != end)
*dest++ = *begin++;
return dest;
}
and when I call the following:
static const double arr[] = {50,23, 56,1,78,23,25,26,143,120};
vector<double> values(arr, arr + sizeof(arr) / sizeof(arr[0]) );
// Using copy
// ----------
vector<double> values_copy;
copy(values.begin(), values.end(), back_inserter(values_copy));
for(int i=0 ; i < values_copy.size(); i++)
cout << values_copy[i] << endl;
I get the following compile error (btw to the g++ developers, thank you):
2-iterator.cpp: In function ‘int main()’:
2-iterator.cpp:77:63: error: call of overloaded ‘copy(std::vector<double>::iterator, std::vector<double>::iterator, std::back_insert_iterator<std::vector<double> >)’ is ambiguous
2-iterator.cpp:77:63: note: candidates are:
2-iterator.cpp:41:5: note: Out copy(In, In, Out) [with In = __gnu_cxx::__normal_iterator<double*, std::vector<double> >, Out = std::back_insert_iterator<std::vector<double> >]
/usr/include/c++/4.6/bits/stl_algobase.h:444:5: note: _OI std::copy(_II, _II, _OI) [with _II = __gnu_cxx::__normal_iterator<double*, std::vector<double> >, _OI = std::back_insert_iterator<std::vector<double> >]
[Finished in 0.7s with exit code 1]
Remove:
using namespace std;
and use std::cout, std::endl, etc. There is already std::copy function.