I have a temporary list that needs to change its elements and erase() them from the list as a way of marking them as done.
std::list<Vertex> temp {vertices.begin(), vertices.end()};
I've tried using Vertex& and Vertex* without success, and the second one makes the code very messy.
What is the proper way to do this? Thanks in advance
Edit: surrounding code
int label = 1;
// change elements without affecting temporary list
std::list<Vertex*> unlabeledVertices {graph.vertices.begin(), graph.vertices.end()};
for (auto iter = unlabeledVertices.begin(); iter != unlabeledVertices.end(); ++label) {
(*iter)->label = label;
// temporary list
std::list<Vertex*> currentLabelVertices;
currentLabelVertices.push_back(*iter);
// check if we can label any other vertex with the current color
auto nestedIter = iter;
for (nestedIter++; nestedIter != unlabeledVertices.end(); ) {
// checking current vertex against any other colored vertex
if (std::none_of(currentLabelVertices.begin(), currentLabelVertices.end(),
[=](const Vertex* v){ return (*nestedIter)->isConnected(*v); })) {
(*nestedIter)->label = label;
currentLabelVertices.push_back(*nestedIter);
nestedIter = unlabeledVertices.erase(nestedIter);
}
else {
nestedIter++;
}
}
iter = unlabeledVertices.erase(iter);
}
Error message:
/usr/bin/g++ -fdiagnostics-color=always -g /home/etzl/projects/c-cpp/test/*.cc -o exec
In file included from /usr/include/x86_64-linux-gnu/c++/10/bits/c++allocator.h:33,
from /usr/include/c++/10/bits/allocator.h:46,
from /usr/include/c++/10/string:41,
from /usr/include/c++/10/bits/locale_classes.h:40,
from /usr/include/c++/10/bits/ios_base.h:41,
from /usr/include/c++/10/ios:42,
from /usr/include/c++/10/ostream:38,
from /usr/include/c++/10/iostream:39,
from /home/etzl/projects/c-cpp/test/main.cc:1:
/usr/include/c++/10/ext/new_allocator.h: In instantiation of ‘void __gnu_cxx::new_allocator<_Tp>::construct(_Up*, _Args&& ...) [with _Up = Vertex*; _Args = {Vertex&}; _Tp = std::_List_node<Vertex*>]’:
/usr/include/c++/10/bits/alloc_traits.h:512:17: required from ‘static void std::allocator_traits<std::allocator<_CharT> >::construct(std::allocator_traits<std::allocator<_CharT> >::allocator_type&, _Up*, _Args&& ...) [with _Up = Vertex*; _Args = {Vertex&}; _Tp = std::_List_node<Vertex*>; std::allocator_traits<std::allocator<_CharT> >::allocator_type = std::allocator<std::_List_node<Vertex*> >]’
/usr/include/c++/10/bits/stl_list.h:637:33: required from ‘std::__cxx11::list<_Tp, _Alloc>::_Node* std::__cxx11::list<_Tp, _Alloc>::_M_create_node(_Args&& ...) [with _Args = {Vertex&}; _Tp = Vertex*; _Alloc = std::allocator<Vertex*>; std::__cxx11::list<_Tp, _Alloc>::_Node = std::__cxx11::list<Vertex*>::_Node]’
/usr/include/c++/10/bits/stl_list.h:1911:32: required from ‘void std::__cxx11::list<_Tp, _Alloc>::_M_insert(std::__cxx11::list<_Tp, _Alloc>::iterator, _Args&& ...) [with _Args = {Vertex&}; _Tp = Vertex*; _Alloc = std::allocator<Vertex*>; std::__cxx11::list<_Tp, _Alloc>::iterator = std::__cxx11::list<Vertex*>::iterator]’
/usr/include/c++/10/bits/stl_list.h:1227:19: required from ‘void std::__cxx11::list<_Tp, _Alloc>::emplace_back(_Args&& ...) [with _Args = {Vertex&}; _Tp = Vertex*; _Alloc = std::allocator<Vertex*>]’
/usr/include/c++/10/bits/stl_list.h:1840:18: required from ‘void std::__cxx11::list<_Tp, _Alloc>::_M_initialize_dispatch(_InputIterator, _InputIterator, std::__false_type) [with _InputIterator = std::_List_iterator<Vertex>; _Tp = Vertex*; _Alloc = std::allocator<Vertex*>]’
/usr/include/c++/10/bits/stl_list.h:806:26: required from ‘std::__cxx11::list<_Tp, _Alloc>::list(_InputIterator, _InputIterator, const allocator_type&) [with _InputIterator = std::_List_iterator<Vertex>; <template-parameter-2-2> = void; _Tp = Vertex*; _Alloc = std::allocator<Vertex*>; std::__cxx11::list<_Tp, _Alloc>::allocator_type = std::allocator<Vertex*>]’
/home/etzl/projects/c-cpp/test/main.cc:58:87: required from here
/usr/include/c++/10/ext/new_allocator.h:150:4: error: cannot convert ‘Vertex’ to ‘Vertex*’ in initialization
150 | { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Build finished with error(s)
You should use std::unordered_set<Vertex*> currentLabelVertices instead of a list. It gives O(1) lookup instead of the O(n) solution you have with std::none_of().
Your other problem is here:
std::list<Vertex*> unlabeledVertices {graph.vertices.begin(), graph.vertices.end()};
It doesn't compile because graph.vertices contains Vertex instances, not pointers. The fix is simple:
std::list<Vertex*> unlabeledVertices;
for (auto& vertex : graph.vertices)
unlabeledVertices.push_back(&vertex);
I'm making a parser combinator in c++. Currently, I'm trying to make a sequence function that will call other parsers in order and return all the results in a Tuple.
Code
template<typename T>
T parse(std::function<T(Stream*)> parser, Stream* stream)
{
return parser(stream);
}
std::function<char(Stream*)> Char(char c)
{
return [=](Stream* stream) -> char {
auto ch = stream->Next();
if (ch == c) {
stream->Consume(1);
return c;
}
return 0;
};
}
template <typename ...T, typename R>
std::function<R(Stream*)> Seq(T... a)
{
return [=](Stream* stream) -> R {
std::tuple tuple = { a(stream)... };
return tuple;
};
}
The problem is that the function Seq needs to know the return type which is a Tuple. This tuple is made of all the results of the functions inside the parameter pack. So I don't know how to tell the compiler what the return type is.
This is the main code.
auto& charA = Char('a');
auto& seq = Seq(Char('#'), charA);
Stream stream("text.txt");
parse(seq, &stream);
Here is the error trace.
TestLayer.cpp(338,27): error C3547: el parámetro de plantilla 'R' no se puede usar porque sigue a un paquete de parámetros de plantilla y no se puede deducir de los parámetros de funciones de 'Seq'
TestLayer.cpp(337): message : vea la declaración de 'R'
TestLayer.cpp(356,14): error C2672: 'Seq': no se encontró una función sobrecargada que coincida
TestLayer.cpp(356,14): error C2783: 'std::function<R(Stream *)> Seq(T...)': no se pudo deducir el argumento de plantilla para 'R'
TestLayer.cpp(338): message : vea la declaración de 'Seq'
TestLayer.cpp(356,12): error C2530: 'seq': se deben inicializar las referencias
TestLayer.cpp(360,11): error C3536: 'seq': no se puede usar antes de inicializarse
TestLayer.cpp(360,2): error C2672: 'parse': no se encontró una función sobrecargada que coincida
TestLayer.cpp(360,20): error C2784: 'T parse(std::function<T(Stream *)>,Stream *)': no se pudo deducir el argumento de plantilla para 'std::function<T(Stream *)>' desde 'int'
TestLayer.cpp(293): message : vea la declaración de 'parse'
Edit:
So, thanks to the comments I came up with this solution:
template <typename ...T>
auto Seq(T... a) -> std::function<decltype(std::tuple{ a(std::declval<Stream*>())... })(Stream*)>
{
return [=](Stream* stream) -> decltype(std::tuple{ a(std::declval<Stream*>())... }) {
std::tuple tuple = { a(stream)... };
return tuple;
};
}
I don't know if it's the optimal solution.
In C++11 you can figure out what std::functions R parameter is supposed to be in different places. I've chosen to make it a template parameter with a default type:
template<
typename... T,
class R = decltype(std::make_tuple(std::declval<T>()(std::declval<Stream*>())...))
>
auto Seq(T... a) -> std::function<R(Stream*)>
{
return [=](Stream* stream) {
return std::make_tuple(a(stream)...);
};
}
Here's an alternative version without that extra template parameter:
template<typename... T>
auto Seq(T... a) ->
std::function<
decltype(
std::make_tuple(std::declval<T>()(std::declval<Stream*>())...)
)(Stream*)
>
{
return [=](Stream* stream) {
return std::make_tuple(a(stream)...);
};
}
In C++17 it is simpler:
template<typename... T>
auto Seq(T... a) {
return std::function([=](Stream* stream) {
return std::make_tuple(a(stream)...);
});
}
I am trying to combine boost::numeric::odeint with an implementation of the System class of my own (see System.hpp).
A (template) System object is used within a BatchFilter class method, like so:
# BatchFilter.cpp
# template <typename state_type> BatchFilter class {...}
System<state_type> dynamics(this -> args,
N_true,
this -> true_dynamics_fun );
typedef boost::numeric::odeint::runge_kutta_cash_karp54< state_type > error_stepper_type;
auto stepper = boost::numeric::odeint::make_controlled<error_stepper_type>( 1.0e-13 , 1.0e-16 );
auto tbegin = T_obs.begin();
auto tend = T_obs.end();
boost::numeric::odeint::integrate_times(stepper, dynamics, X0_true_copy, tbegin, tend,0.1,
Observer::push_back_state(this -> true_state_history));
BatchFilter is a template derived class which I am explicitly instantiating at the bottom of BatchFilter.cpp. The two explicit instantiations are
template class BatchFilter< arma::vec >;
template class BatchFilter< arma::vec::fixed<2> >;
The Base class is also explicitly instantiated. I must use arma::vec::fixed<2> since using arma::vec within odeint causes a runtime crash as the state will not have the proper size.
What does not work?
The instantiation with arma::vec::fixed<2> fails while the one with arma::vec succeeds. The compiler complains about an illegal binding:
cannot bind non-const lvalue reference of type'arma::Col<double>::fixed<2>&' to an rvalue of type'arma::Col<double>::fixed<2>' sys( x , m_dxdt.m_v ,t );
What puzzles me is that everything works fine when the explicit instantiation of BatchFilter< arma::vec > succeeds while BatchFilter< arma::vec::fixed<2> > fails.
Any insight as to what is going on?
[ 3%] Building CXX object CMakeFiles/ASPEN.dir/source/BatchFilter.cpp.o
In file included from /usr/local/include/boost/numeric/odeint.hpp:35:0,
from /Users/bbercovici/GDrive/CUBoulder/Research/code/ASPEN_gui_less/lib/include/Filter.hpp:5,
from /Users/bbercovici/GDrive/CUBoulder/Research/code/ASPEN_gui_less/lib/include/BatchFilter.hpp:5,
from /Users/bbercovici/GDrive/CUBoulder/Research/code/ASPEN_gui_less/lib/source/BatchFilter.cpp:1:
/usr/local/include/boost/numeric/odeint/stepper/controlled_runge_kutta.hpp: In instantiation of 'boost::numeric::odeint::controlled_step_result boost::numeric::odeint::controlled_runge_kutta<ErrorStepper, ErrorChecker, StepAdjuster, Resizer, boost::numeric::odeint::explicit_error_stepper_tag>::try_step_v1(System, StateInOut&, boost::numeric::odeint::controlled_runge_kutta<ErrorStepper, ErrorChecker, StepAdjuster, Resizer, boost::numeric::odeint::explicit_error_stepper_tag>::time_type&, boost::numeric::odeint::controlled_runge_kutta<ErrorStepper, ErrorChecker, StepAdjuster, Resizer, boost::numeric::odeint::explicit_error_stepper_tag>::time_type&) [with System = System<arma::Col<double>::fixed<2>, arma::Mat<double> >; StateInOut = arma::Col<double>; ErrorStepper = boost::numeric::odeint::runge_kutta_cash_karp54<arma::Col<double> >; ErrorChecker = boost::numeric::odeint::default_error_checker<double, boost::numeric::odeint::range_algebra, boost::numeric::odeint::default_operations>; StepAdjuster = boost::numeric::odeint::default_step_adjuster<double, double>; Resizer = boost::numeric::odeint::initially_resizer; boost::numeric::odeint::controlled_runge_kutta<ErrorStepper, ErrorChecker, StepAdjuster, Resizer, boost::numeric::odeint::explicit_error_stepper_tag>::time_type = double]':
/usr/local/include/boost/numeric/odeint/stepper/controlled_runge_kutta.hpp:283:27: required from 'boost::numeric::odeint::controlled_step_result boost::numeric::odeint::controlled_runge_kutta<ErrorStepper, ErrorChecker, StepAdjuster, Resizer, boost::numeric::odeint::explicit_error_stepper_tag>::try_step(System, StateInOut&, boost::numeric::odeint::controlled_runge_kutta<ErrorStepper, ErrorChecker, StepAdjuster, Resizer, boost::numeric::odeint::explicit_error_stepper_tag>::time_type&, boost::numeric::odeint::controlled_runge_kutta<ErrorStepper, ErrorChecker, StepAdjuster, Resizer, boost::numeric::odeint::explicit_error_stepper_tag>::time_type&) [with System = System<arma::Col<double>::fixed<2>, arma::Mat<double> >; StateInOut = arma::Col<double>; ErrorStepper = boost::numeric::odeint::runge_kutta_cash_karp54<arma::Col<double> >; ErrorChecker = boost::numeric::odeint::default_error_checker<double, boost::numeric::odeint::range_algebra, boost::numeric::odeint::default_operations>; StepAdjuster = boost::numeric::odeint::default_step_adjuster<double, double>; Resizer = boost::numeric::odeint::initially_resizer; boost::numeric::odeint::controlled_runge_kutta<ErrorStepper, ErrorChecker, StepAdjuster, Resizer, boost::numeric::odeint::explicit_error_stepper_tag>::time_type = double]'
/usr/local/include/boost/numeric/odeint/integrate/detail/integrate_times.hpp:101:81: required from 'size_t boost::numeric::odeint::detail::integrate_times(Stepper, System, State&, TimeIterator, TimeIterator, Time, Observer, boost::numeric::odeint::controlled_stepper_tag) [with Stepper = boost::numeric::odeint::controlled_runge_kutta<boost::numeric::odeint::runge_kutta_cash_karp54<arma::Col<double> >, boost::numeric::odeint::default_error_checker<double, boost::numeric::odeint::range_algebra, boost::numeric::odeint::default_operations>, boost::numeric::odeint::default_step_adjuster<double, double>, boost::numeric::odeint::initially_resizer, boost::numeric::odeint::explicit_error_stepper_tag>; System = System<arma::Col<double>::fixed<2>, arma::Mat<double> >; State = arma::Col<double>; TimeIterator = __gnu_cxx::__normal_iterator<const double*, std::vector<double> >; Time = double; Observer = Observer::push_back_state<arma::Col<double> >; size_t = long unsigned int]'
/usr/local/include/boost/numeric/odeint/integrate/integrate_times.hpp:129:35: required from 'size_t boost::numeric::odeint::integrate_times(Stepper, System, State&, TimeIterator, TimeIterator, Time, Observer) [with Stepper = boost::numeric::odeint::controlled_runge_kutta<boost::numeric::odeint::runge_kutta_cash_karp54<arma::Col<double> >, boost::numeric::odeint::default_error_checker<double, boost::numeric::odeint::range_algebra, boost::numeric::odeint::default_operations>, boost::numeric::odeint::default_step_adjuster<double, double>, boost::numeric::odeint::initially_resizer, boost::numeric::odeint::explicit_error_stepper_tag>; System = System<arma::Col<double>::fixed<2>, arma::Mat<double> >; State = arma::Col<double>; TimeIterator = __gnu_cxx::__normal_iterator<const double*, std::vector<double> >; Time = double; Observer = Observer::push_back_state<arma::Col<double> >; size_t = long unsigned int]'
/Users/bbercovici/GDrive/CUBoulder/Research/code/ASPEN_gui_less/lib/source/BatchFilter.cpp:231:42: required from void BatchFilter<state_type>::compute_reference_state_history(const std::vector<double>&, std::vector<_RealType>&, std::vector<arma::Mat<double> >&) [with state_type = arma::Col<double>::fixed<2>]'
/Users/bbercovici/GDrive/CUBoulder/Research/code/ASPEN_gui_less/lib/source/BatchFilter.cpp:327:16: required from here
/usr/local/include/boost/numeric/odeint/stepper/controlled_runge_kutta.hpp:481:12: error: no match for call to '(boost::numeric::odeint::unwrap_reference<System<arma::Col<double>::fixed<2>, arma::Mat<double> > >::type {aka System<arma::Col<double>::fixed<2>, arma::Mat<double> >}) (arma::Col<double>&, arma::Col<double>&, boost::numeric::odeint::controlled_runge_kutta<boost::numeric::odeint::runge_kutta_cash_karp54<arma::Col<double> >, boost::numeric::odeint::default_error_checker<double, boost::numeric::odeint::range_algebra, boost::numeric::odeint::default_operations>, boost::numeric::odeint::default_step_adjuster<double, double>, boost::numeric::odeint::initially_resizer, boost::numeric::odeint::explicit_error_stepper_tag>::time_type&)'
sys( x , m_dxdt.m_v ,t );
~~~^~~~~~~~~~~~~~~~~~~~~
In file included from /Users/bbercovici/GDrive/CUBoulder/Research/code/ASPEN_gui_less/lib/include/Filter.hpp:6:0,
from /Users/bbercovici/GDrive/CUBoulder/Research/code/ASPEN_gui_less/lib/include/BatchFilter.hpp:5,
from /Users/bbercovici/GDrive/CUBoulder/Research/code/ASPEN_gui_less/lib/source/BatchFilter.cpp:1:
/Users/bbercovici/GDrive/CUBoulder/Research/code/ASPEN_gui_less/lib/include/System.hpp:32:7: note: candidate: void System<state_type, jacobian_type>::operator()(const state_type&, state_type&, double) [with state_type = arma::Col<double>::fixed<2>; jacobian_type = arma::Mat<double>] <near match>
void operator() (const state_type & x , state_type & dxdt , const double t ){
^~~~~~~~
/Users/bbercovici/GDrive/CUBoulder/Research/code/ASPEN_gui_less/lib/include/System.hpp:32:7: note: conversion of argument 2 would be ill-formed:
In file included from /usr/local/include/boost/numeric/odeint.hpp:35:0,
from /Users/bbercovici/GDrive/CUBoulder/Research/code/ASPEN_gui_less/lib/include/Filter.hpp:5,
from /Users/bbercovici/GDrive/CUBoulder/Research/code/ASPEN_gui_less/lib/include/BatchFilter.hpp:5,
from /Users/bbercovici/GDrive/CUBoulder/Research/code/ASPEN_gui_less/lib/source/BatchFilter.cpp:1:
/usr/local/include/boost/numeric/odeint/stepper/controlled_runge_kutta.hpp:481:25: error: cannot bind non-const lvalue reference of type 'arma::Col<double>::fixed<2>&' to an rvalue of type 'arma::Col<double>::fixed<2>'
sys( x , m_dxdt.m_v ,t );
~~~~~~~^~~
In file included from /usr/local/include/armadillo:568:0,
from /Users/bbercovici/GDrive/CUBoulder/Research/code/ASPEN_gui_less/lib/include/BatchFilter.hpp:4,
from /Users/bbercovici/GDrive/CUBoulder/Research/code/ASPEN_gui_less/lib/source/BatchFilter.cpp:1:
/usr/local/include/armadillo_bits/Col_meat.hpp:1145:1: note: after user-defined conversion: arma::Col<eT>::fixed<fixed_n_elem>::fixed(const arma::Base<eT, T1>&) [with T1 = arma::Mat<double>; long long unsigned int fixed_n_elem = 2; eT = double]
Col<eT>::fixed<fixed_n_elem>::fixed(const Base<eT,T1>& A)
^~~~~~~
make[2]: *** [CMakeFiles/ASPEN.dir/source/BatchFilter.cpp.o] Error 1
make[1]: *** [CMakeFiles/ASPEN.dir/all] Error 2
make: *** [all] Error 2
For reference, System.hpp is down here:
# System.hpp
template <typename state_type,typename jacobian_type = arma::mat> class System {
public:
System(const Args & args,
unsigned int N_est,
state_type (*estimate_dynamics_fun)(double, const state_type & , const Args & args) ,
jacobian_type (*jacobian_estimate_dynamics_fun)(double, const state_type & , const Args & args),
unsigned int N_true = 0,
state_type (*true_dynamics_fun)(double, const state_type & , const Args & args) = nullptr)
: N_est(N_est), N_true(N_true){
this -> estimate_dynamics_fun = estimate_dynamics_fun;
this -> true_dynamics_fun = estimate_dynamics_fun;
this -> jacobian_estimate_dynamics_fun = jacobian_estimate_dynamics_fun;
this -> args = args;
}
System(const Args & args,
unsigned int N_true,
state_type (*true_dynamics_fun)(double, const state_type & , const Args & args))
: N_est(0), N_true(N_true){
this -> true_dynamics_fun = true_dynamics_fun;
this -> args = args;
}
void operator() (const state_type & x , state_type & dxdt , const double t ){
if (this -> true_dynamics_fun != nullptr){
dxdt.rows(this -> N_est + this -> N_est * this -> N_est,
this -> N_est + this -> N_est * this -> N_est + this -> N_true - 1) = this -> true_dynamics_fun(t,
x.rows(this -> N_est + this -> N_est * this -> N_est,
this -> N_est + this -> N_est * this -> N_est + this -> N_true - 1),args);
}
if (this -> estimate_dynamics_fun != nullptr){
arma::mat Phi = arma::reshape(x.rows(this -> N_est,
this -> N_est + this -> N_est * this -> N_est - 1), this -> N_est, this -> N_est );
arma::mat A = this -> jacobian_estimate_dynamics_fun(t,x.rows(0,this -> N_est - 1),this -> args);
dxdt.rows(0,this -> N_est - 1) = this -> estimate_dynamics_fun(t,x.rows(0,this -> N_est - 1),this -> args);
dxdt.rows(this -> N_est,
this -> N_est + this -> N_est * this -> N_est - 1) = arma::vectorise(A * Phi);
}
}
protected:
const unsigned int N_est;
const unsigned int N_true;
state_type (*estimate_dynamics_fun)(double, const state_type & , const Args & args) = nullptr;
state_type (*true_dynamics_fun)(double, const state_type & , const Args & args) = nullptr;
jacobian_type (*jacobian_estimate_dynamics_fun)(double, const state_type & , const Args & args) = nullptr;
Args args;
};
I found a way around the resizing issue here:
https://reformatcode.com/code/c/armadillo-conflicts-with-boost-odeint-odeint-resizes-the-state-vector-to-zero-during-integration
The solution consists in extending boost:numeric::odeint with the following adapters that handle automatic resizing of the arma::vec for safe use with odeint
#include <armadillo>
namespace boost { namespace numeric { namespace odeint {
template <>
struct is_resizeable<arma::vec>
{
typedef boost::true_type type;
const static bool value = type::value;
};
template <>
struct same_size_impl<arma::vec, arma::vec>
{
static bool same_size(const arma::vec & x, const arma::vec& y)
{
return x.n_rows == y.n_rows;
}
};
template<>
struct resize_impl<arma::vec, arma::vec>
{
static void resize(arma::vec &v1, const arma::vec & v2)
{
v1.resize(v2.n_rows,1);
}
};
} } } // namespace boost::numeric::odeint
im trying to import data from an XML file and save them in a 5D map
// declaration of the map
map<char *, map<char *, map<char*, map<char *, map<char*, map<char*, char*, cmp_str>, cmp_str>, cmp_str>, cmp_str>, cmp_str>, cmp_str> XmlData;
im using for the XML-Parsing the RapidXML Parser
file<> xmlFile("jobs.xml");
xml_document<> doc;
doc.parse<0>(xmlFile.data());
xml_node<> *node = doc.first_node();
while(node != 0) {
xml_node<> *child = node->first_node();
while (child != 0)
{
xml_node<> *subchild = child->first_node();
while (subchild != 0)
{
xml_node<> *subsubchild = subchild->first_node();
while (subsubchild != 0)
{
xml_node<> *subsubsubchild = subchild->first_node();
while (subsubsubchild != 0)
{
// the error appears here
XmlData[node->name()][child->name()][subchild->name()][subsubchild->name()][subsubsubchild->name()] = subsubsubchild->value();
subsubsubchild = subsubsubchild->next_sibling();
}
subsubchild = subsubchild->next_sibling();
}
subchild = subchild->next_sibling();
}
child = child->next_sibling();
}
node = node->next_sibling();
}
I had to use 5 while loops to iterate all nodes
XML :
<Job>
<UserJob>
<RuleSet>
<def>
<Path>detection_c_new.dcp</Path>
<WkspName>MyWS</WkspName>
<UserName>Admin</UserName>
</def>
</RuleSet>
</UserJob>
<Scenes>
<Scene1>
<Info>
<def>
<ID>0</ID>
<Name>Scene 1</Name>
</def>
</Info>
<Layers>
<Layer1>
<Index>0</Index>
<Name>Layer 1</Name>
<ImgPath>CTX_MEM_Detail.jpg</ImgPath>
</Layer1>
</Layers>
<ExpItems>
<ExpItem1>
<Name>MyStats1</Name>
<Driver>CSV</Driver>
<Type>1</Type>
<Path>CTX_MEM_Detail.csv</Path>
</ExpItem1>
</ExpItems>
</Scene1>
</Scenes>
</Job>
When compiling using g++ with c++0x under CentOS 6 i get this following error:
Job.cpp:133: error: no match for âoperator=â in â((std::map<char*, std::map<char*, char*, cmp_str, std::allocator<std::pair<char* const, char*> > >, cmp_str, std::all$
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/stl_map.h:251: note: candidates are: std::map<_Key, _Tp, _Compare, _Alloc>& std::map<_Key, _Tp, _Compa$
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/stl_map.h:266: note: std::map<_Key, _Tp, _Compare, _Alloc>& std::map<_Key, _Tp, _Compa$
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/stl_map.h:286: note: std::map<_Key, _Tp, _Compare, _Alloc>& std::map<_Key, _Tp, _Compa$
char* is an awful thing to have as map key, and probably value too.
You might use const char* as key is absolutely sure that you pass pointers to stable things, like literal only.
The baseline soulution would use string as both key and payload, and I guess your problem would go away too. The most probable immediate cause is that your value refuses to convert to char*.