I try to convert form matrix in Opencv to matrix in armadillo
I found this func in this link
but when I try to call it give me error :
error C2783: 'arma::Mat cvMat2armaMat(cv::Mat &)' : could not deduce template argument for 'T3'
IntelliSense: no instance of function template "cvMat2armaMat" matches the argument list
This is function :
template<class T3>
arma::Mat <T3> cvMat2armaMat(cv::Mat & cvMatIn)
{
return armaConv (cvMatIn.data, cvMatIn.rows, cvMatIn.cols,false);
}
This is function calling ( the error appear when I call func )
cv::Mat CurrentImage = imread(path, 0);
arma::mat singleImage = cvMat2armaMat (CurrentImage);
what should I do ?
You need to specify the type of arma::mat<XXX> that cvMat2armaMat() returns.
What is armaConv?
Maybe you meant this:
template<class T3>
arma::Mat <T3> cvMat2armaMat(cv::Mat & cvMatIn)
{
return arma::Mat <T3> (cvMatIn.data, cvMatIn.rows, cvMatIn.cols,false);
}
and the call is this:
auto singleImage = cvMat2armaMat<float>(CurrentImage);
or you'll need to switch on the cv::Mat type.
I can answer how to do this on VC10 and g++ but I still have a few issues to be resolved. I am new to writing templated functions. It is often necessary to convert between cv::Mat and arma::mat matrix objects since Armadillo has more complete Linear Algebra facilities. OpenCV stores it's matrices in row-major order while Armadillo stores it's matrices in column-major order which is one component of this problem. I have created the following templated functions that have been tested in VC10 and g++ 4.9 to work on both float and double type matrices:
template<typename T>
static void Cv_mat_to_arma_mat(const cv::Mat_<T>& cv_mat_in, arma::Mat<T>& arma_mat_out)
{
cv::Mat_<T> temp(cv_mat_in.t()); //todo any way to not create a temporary?
#if defined(WIN32)
//This compiles on VC10 but not g++ 4.9 (on Debian with OpenCV 2.4.9.1 and Arma 4.320.0)
arma_mat_out = arma::Mat<T>(temp.ptr<T>(), //<<"error: expected primary-expression before '(' token"
static_cast<arma::uword>(temp.cols),
static_cast<arma::uword>(temp.rows),
true,
true);
#elif defined(LINUX)
//This compiles on both but is not as nice
arma_mat_out = arma::Mat<T>(reinterpret_cast<T*>(temp.data),
static_cast<arma::uword>(temp.cols),
static_cast<arma::uword>(temp.rows),
true,
true);
#endif
};
//This one is fine on both
template<typename T>
static void Arma_mat_to_cv_mat(const arma::Mat<T>& arma_mat_in,cv::Mat_<T>& cv_mat_out)
{
cv::transpose(cv::Mat_<T>(static_cast<int>(arma_mat_in.n_cols),
static_cast<int>(arma_mat_in.n_rows),
const_cast<T*>(arma_mat_in.memptr())),
cv_mat_out);
};
This code can be run with:
std::cout << "Testing arma::mat<->cv::Mat <double>:" << std::endl;
{
arma::Mat<double> A(3,2);
A << 1 << 2 << arma::endr
<< 3 << 4 << arma::endr
<< 5 << 6 << arma::endr;
cv::Mat_<double> cv_A(3,2);
M_math::Arma_mat_to_cv_mat<double>(A, cv_A);
std::cout << "Arma_mat_to_cv_mat<double>" << std::endl;
std::cout << A << std::endl;
std::cout << cv_A << std::endl;
std::cout << "Cv_mat_to_arma_mat<double>" << std::endl;
M_math::Cv_mat_to_arma_mat<double>(cv_A, A);
std::cout << cv_A << std::endl;
std::cout << A << std::endl;
}
std::cout << "Now <float>" << std::endl;
{
arma::Mat<float> A(3,2);
A << 1 << 2 << arma::endr
<< 3 << 4 << arma::endr
<< 5 << 6 << arma::endr;
cv::Mat_<float> cv_A(3,2);
M_math::Arma_mat_to_cv_mat<float>(A, cv_A);
std::cout << "Arma_mat_to_cv_mat<float>" << std::endl;
std::cout << A << std::endl;
std::cout << cv_A << std::endl;
std::cout << "Cv_mat_to_arma_mat<float>" << std::endl;
M_math::Cv_mat_to_arma_mat<float>(cv_A, A);
std::cout << cv_A << std::endl;
std::cout << A << std::endl;
}
My further questions are:
Any idea what I am doing wrong? This seems like it is a case of VC10 being more permissive than g++ but what am I missing if I want to keep using the first (nicer) version with g++?
In Cv_mat_to_arma_mat(...) are there any suggestions to get around the row-major order vs row-order issue without creating a temporary? cv_mat_in.t() does not alter the internal memory pointer in cv_mat_in, it is just a cv::MatExpr.
Any criticism of the style, safety, or performance of these functions would be appreciated. Of course they will not work with cv::Mat's that have more than one channel.
Related
I am using a function that returns 3 values using tuples in C++17.
The program is
void test_noisy()
{
s4prc::Noisy<s4prc::StrVec> big{s4prc::makeStrVec(10'000)};
std::cout << ">>> big=" << big << '\n';
s4prc::Noisy<std::string> evenStr;
s4prc::Noisy<std::string> oddStr;
int totalLength;
auto [evenStr, oddStr, totalLength]=s4prc::manyResults(big);
}
When I compile, I obtain this error :
error: expected unqualified-id before ‘[’ token
auto [evenStr, oddStr, totalLength]=s4prc::manyResults(big);
^
GNUmakefile:192 : la recette pour la cible « prog.o » a échouée
Thanks,
Younès
Not sure it's the only problem but... with
s4prc::Noisy<std::string> evenStr;
s4prc::Noisy<std::string> oddStr;
int totalLength;
auto [evenStr, oddStr, totalLength]=s4prc::manyResults(big);
you're defining and redefining evenStr, oddStr and totalLength. This should give a compilation error.
Try deleting the first definitions (the three rows before auto).
Second: are you sure you're compiling C++17?
The answer that I find is to use make_tuple in the return of the definition of the function;
return std::make_tuple(std::move(even), // std::move() prevents from
std::move(odd), // copying existing locals
std::move(length)); // to tupl
Besides, when calling the function use :
auto data=s4prc::manyResults(big);
and get the three compounents of data with :
std::cout << ">>> evenStr=" << std::get<0>(data) << '\n';
std::cout << ">>> oddStr=" << std::get<1>(data) << '\n';
std::cout << ">>> totalLength=" << std::get<2>(data) << '\n';
During my work, it would be a requirement for me to use Eigen::VectorXcd as state type, to solve a huge linear ODE system. In that project, the matrix in the ODE system is sparse. Multiplying a it with a dense vector can be computed in parallel in a simple way using Eigen. However, I have faced some problems in that situation that I will tell in details below. Currently I am applying a not-so efficient solution, namely, I use arma::cx_vec as state type, and declare the matrix corresponding the ode arma::cx_mat, which is a dense matrix type. Unfortunately, sparse-matrix-dense vector multiplication cannot be parallelized with Armadillo since it supports only the single-threaded version of SuperLU. According to my experience, in my specific case, sparse matrix-dense vector multiplication is three times faster than dense matrix-dense vector multiplication. Since a single running lasts for tens or hundreds of hours even when using 20 CPU cores simultaneously, it would be highly required for me to be able to use the Eigen library along with boost::odeint to gain a factor of three in runtime.
For testing purposes, I tried to use Eigen::VectorXd as a state type. I have also found very similar situations, see: Using Boost::odeint with Eigen::Matrix as a state vector or using several eigen matrices as statetypes in boost/odeint. However, none of the solutions worked for me. In my real project, I have to use the Bulirsch-Stoer method to integrate my ODE system since high precision and therefore error control is necessary for me. Below I will post my test code, corresponding to Eigen::VectorXd state type. As you can see, for first, I followed the steps described in the boost::odeint documentation: I defined my state vector resizeable and overloaded the mathematical operators used by the vector space algebra of the controlled stepper. After these steps, the code still did not compile, overloading of the addition operator for adding vectors to scalars was also necessary. Here is my code:
#include <iostream>
#include <vector>
#include <complex>
#include <Eigen/Eigen>
#include <boost/numeric/odeint.hpp>
namespace boost {
namespace numeric {
namespace odeint {
template<>
struct is_resizeable<Eigen::VectorXd>
{
typedef boost::true_type type;
static const bool value = type::value;
};
template<>
struct same_size_impl<Eigen::VectorXd, Eigen::VectorXd>
{
static bool same_size(const Eigen::VectorXd& v1, const Eigen::VectorXd& v2)
{
std::cout << "same_size: " << v1.transpose() << " and " << v2.transpose() << std::endl;
std::cout << "same_size: " << v1.rows() << " == " << v2.rows() << std::endl;
return v1.rows() == v2.rows();
}
};
template<>
struct resize_impl<Eigen::VectorXd, Eigen::VectorXd>
{
static void resize(Eigen::VectorXd& v1, const Eigen::VectorXd& v2)
{
std::cout << "resize_impl: " << v1.transpose() << " and " << v2.transpose() << std::endl;
std::cout << "resize_impl: (" << v1.rows() << " x " << v1.cols() << ") to (" << v2.rows() << " x " << v2.cols() << ")" << std::endl;
v1.conservativeResize(v2.size());
std::cout << "resize_impl: new size: " << v1.rows() << " x " << v1.cols() << std::endl;
}
};
template<>
struct vector_space_norm_inf<Eigen::VectorXd>
{
typedef double result_type;
double operator()(const Eigen::VectorXd& v) const
{
std::cout << "vector_space_norm_inf(" << v.transpose() << ") = " << v.lpNorm<Eigen::Infinity>() << std::endl;
return v.lpNorm<Eigen::Infinity>();
}
};
}
}
}
namespace Eigen {
//VectorXd operator*(const double& a, const VectorXd& v)
//{
// std::cout << a << "*(" << v.transpose() << ") = " << a*(v.transpose()) << std::endl;
// return a*v;
//}
//
//VectorXd operator*(const VectorXd& v, const double& a)
//{
// std::cout << "(" << v.transpose() << ")*" << v.transpose() << " = " << a*(v.transpose()) << std::endl;
// return a*v;
//}
//
//VectorXd& operator*=(const double& a, VectorXd& v)
//{
// std::cout << "operator*=(const double& a, VectorXd& v): (" << v.transpose() << ") *= " << a << ": ";
// v *= a;
// std::cout << v.transpose() << std::endl;
// return v;
//}
//
//VectorXd& operator*=(VectorXd& v, const double& a)
//{
// std::cout << "operator*=(VectorXd& v, const double& a): (" << v.transpose() << ") *= " << a << ": ";
// v *= a;
// std::cout << v.transpose() << std::endl;
// return v;
//}
//
//VectorXd& operator+=(VectorXd& v1, const VectorXd& v2)
//{
// std::cout << "(" << v1.transpose() << ") += (" << v2.transpose() << "): ";
// v1 += v2;
// std::cout << v1.transpose() << std::endl;
// return v1;
//}
VectorXd operator/(const VectorXd& v1, const VectorXd& v2)
{
const char* sizeeq;
if(v1.size() == v2.size())
sizeeq = "True";
else
sizeeq = "FALSE!";
std::cout << "operator/: size check: " << v1.size() << " ?= " << v2.size() << ": " << sizeeq << std::endl;
VectorXd result(v1.cwiseQuotient(v2));
std::cout << "(" << v1.transpose() << ") / (" << v2.transpose() << ") = " << result.transpose() << std::endl;
return result;
}
VectorXd operator+(double d, const VectorXd& v)
{
std::cout << d << " + (" << v.transpose() << ") = " << d+v.transpose() << std::endl;
return d+v;
}
VectorXd operator+(const VectorXd& v, double d)
{
std::cout << "(" << v.transpose() << ") + " << d << " = " << d+v.transpose() << std::endl;
return d+v;
}
VectorXd abs(const VectorXd& v)
{
std::cout << "|(" << v.transpose() << ")| = " << v.cwiseAbs().transpose() << std::endl;
return v.cwiseAbs();
}
}
typedef Eigen::VectorXd state_type;
typedef Eigen::MatrixXd coeff_matrix_type;
class lin_diff_eq
{
public:
lin_diff_eq(coeff_matrix_type gam): m_gam(gam) {}
coeff_matrix_type get_matrix() const { return m_gam; }
void operator()(const state_type& x, state_type& dxdt, const double t)
{
std::cout << "size: " << x.size() << std::endl;
std::cout << x.transpose() << std::endl;
dxdt = m_gam*x;
}
private:
coeff_matrix_type m_gam;
};
using namespace boost::numeric::odeint;
int main()
{
coeff_matrix_type A = coeff_matrix_type(2,2);
state_type x = state_type(2);
double epsabs = 1e-4;
double epsrel = 1e-4;
A << 0, 1,
-2, 0;
x << 1, 0;
lin_diff_eq lde(A);
std::cout << lde.get_matrix() << std::endl;
integrate_adaptive(bulirsch_stoer<state_type, double, state_type, double, vector_space_algebra>(epsabs, epsrel), lin_diff_eq(A), x, 0.0, 1.0, 0.1);
}
All these steps made my code compile, however, during runtime my program crashes with segmentation fault. As you can see, I overloaded all the operators such that they produce some kind of a very simple log, I couldn't figure out how to produce a more detailed log to locate exactly where and why the segmentation fault occurs. According to the boost::odeint documentation, this can happen during runtime when the vector space algebra doesn't know how to resize the vectors, but I already defined how to do it. On my computer, it can be seen that boost::odeint generates some internal states, resizes them correctly, computes elementwise abs() correctly, but after that it crashes.
The next thing I tried was to use the support to Eigen provided by the boost::odeint developers. In this case, I did not use any of the template specializations and the operator overloads provided above, but instead, I included
boost/numeric/odeint/external/eigen/eigen_algebra.hpp
after including odeint.hpp. The code did not compile, I got the following error messages:
/usr/local/include/boost/numeric/odeint/external/eigen/eigen_algebra.hpp|35|error: ‘scalar_add_op’ in namespace ‘Eigen::internal’ does not name a type|
/usr/local/include/boost/numeric/odeint/external/eigen/eigen_algebra.hpp|35|error: expected template-argument before ‘<’ token|
/usr/local/include/boost/numeric/odeint/external/eigen/eigen_algebra.hpp|35|error: expected ‘>’ before ‘<’ token|
/usr/local/include/boost/numeric/odeint/external/eigen/eigen_algebra.hpp|37|error: wrong number of template arguments (1, should be 2)|
/usr/local/include/Eigen/src/Core/util/ForwardDeclarations.h|91|error: provided for ‘template<class UnaryOp, class MatrixType> class Eigen::CwiseUnaryOp’|
/usr/local/include/boost/numeric/odeint/external/eigen/eigen_algebra.hpp|38|error: expected ‘::’ before ‘operator’|
/usr/local/include/boost/numeric/odeint/external/eigen/eigen_algebra.hpp|38|error: expected identifier before ‘operator’|
/usr/local/include/boost/numeric/odeint/external/eigen/eigen_algebra.hpp||In function ‘const int Eigen::operator+(const Eigen::MatrixBase<Derived>&, const typename Eigen::internal::traits<T>::Scalar&)’:|
/usr/local/include/boost/numeric/odeint/external/eigen/eigen_algebra.hpp|41|error: ‘scalar_add_op’ in namespace ‘Eigen::internal’ does not name a type|
/usr/local/include/boost/numeric/odeint/external/eigen/eigen_algebra.hpp|41|error: expected template-argument before ‘<’ token|
/usr/local/include/boost/numeric/odeint/external/eigen/eigen_algebra.hpp|41|error: expected ‘>’ before ‘<’ token|
/usr/local/include/boost/numeric/odeint/external/eigen/eigen_algebra.hpp|43|error: wrong number of template arguments (1, should be 2)|
/usr/local/include/Eigen/src/Core/util/ForwardDeclarations.h|91|error: provided for ‘template<class UnaryOp, class MatrixType> class Eigen::CwiseUnaryOp’|
/usr/local/include/boost/numeric/odeint/external/eigen/eigen_algebra.hpp|43|error: expected ‘::’ before ‘(’ token|
/usr/local/include/boost/numeric/odeint/external/eigen/eigen_algebra.hpp|43|error: expected identifier before ‘(’ token|
/usr/local/include/boost/numeric/odeint/external/eigen/eigen_algebra.hpp|43|error: ‘scalar_add_op’ is not a member of ‘Eigen::internal’|
/usr/local/include/boost/numeric/odeint/external/eigen/eigen_algebra.hpp|44|error: expected ‘(’ before ‘>’ token|
/usr/local/include/boost/numeric/odeint/external/eigen/eigen_algebra.hpp|50|error: ‘scalar_add_op’ in namespace ‘Eigen::internal’ does not name a type|
/usr/local/include/boost/numeric/odeint/external/eigen/eigen_algebra.hpp|50|error: expected template-argument before ‘<’ token|
/usr/local/include/boost/numeric/odeint/external/eigen/eigen_algebra.hpp|50|error: expected ‘>’ before ‘<’ token|
/usr/local/include/boost/numeric/odeint/external/eigen/eigen_algebra.hpp|52|error: wrong number of template arguments (1, should be 2)|
/usr/local/include/Eigen/src/Core/util/ForwardDeclarations.h|91|error: provided for ‘template<class UnaryOp, class MatrixType> class Eigen::CwiseUnaryOp’|
/usr/local/include/boost/numeric/odeint/external/eigen/eigen_algebra.hpp|53|error: expected ‘::’ before ‘operator’|
/usr/local/include/boost/numeric/odeint/external/eigen/eigen_algebra.hpp|53|error: expected identifier before ‘operator’|
/usr/local/include/boost/numeric/odeint/external/eigen/eigen_algebra.hpp||In function ‘const int Eigen::operator+(const typename Eigen::internal::traits<T>::Scalar&, const Eigen::MatrixBase<Derived>&)’:|
/usr/local/include/boost/numeric/odeint/external/eigen/eigen_algebra.hpp|56|error: ‘scalar_add_op’ in namespace ‘Eigen::internal’ does not name a type|
/usr/local/include/boost/numeric/odeint/external/eigen/eigen_algebra.hpp|56|error: expected template-argument before ‘<’ token|
/usr/local/include/boost/numeric/odeint/external/eigen/eigen_algebra.hpp|56|error: expected ‘>’ before ‘<’ token|
/usr/local/include/boost/numeric/odeint/external/eigen/eigen_algebra.hpp|58|error: wrong number of template arguments (1, should be 2)|
/usr/local/include/Eigen/src/Core/util/ForwardDeclarations.h|91|error: provided for ‘template<class UnaryOp, class MatrixType> class Eigen::CwiseUnaryOp’|
/usr/local/include/boost/numeric/odeint/external/eigen/eigen_algebra.hpp|58|error: expected ‘::’ before ‘(’ token|
/usr/local/include/boost/numeric/odeint/external/eigen/eigen_algebra.hpp|58|error: expected identifier before ‘(’ token|
/usr/local/include/boost/numeric/odeint/external/eigen/eigen_algebra.hpp|58|error: ‘scalar_add_op’ is not a member of ‘Eigen::internal’|
/usr/local/include/boost/numeric/odeint/external/eigen/eigen_algebra.hpp|59|error: expected ‘(’ before ‘>’ token|
||=== Build failed: 32 error(s), 0 warning(s) (0 minute(s), 7 second(s)) ===|
I also tried to include
boost/numeric/odeint/external/eigen/eigen.hpp
instead of eigen_algebra.hpp and received the same error messages when including eigen_algebra.hpp. It seems like Boost::odeint v1.65.1 is not compatible with Eigen v3.3.4. My question is if there is an (un)official header file that provides a support of Eigen 3.3.4 to Boost::odeint 1.65.1, or did I make something wrong during template specializations and/or operator overloading for the vector space algebra?
I also found a solution for "typecasting" std std::vector<> to Eigen::VectorXd
and vice versa, but I think that using std::vector as a state stype, and then internally "casting it" to Eigen::VectorXd, then "casting the result back" to std::vector<> would result in a lower performance than that of mentioned in the introduction since my vectors are huge and ten tousands or more accepted steps are required to perform an integration. I hope my question was accurate enough and the community can kindly help me solving my problem.
Well i was creating a program in c++ .Then i noticed that there were some error due to which my program was not functioning correctly
compiler used:- Dev c++
Error was this:-
Suppose n1=274877906944 which is 2^38. so log(n1) should be 38 which is correct. now let n2=274877906942 which is smaller than n1.
So that means if we calculate log(n2) then it must give me less than log(n1).But log(n2) gave me the same result as log(n1) which is 38.
Which is wrong!!!
Someone please explain this stuff..
You see the result that you do because of rounding. If you increase your precision, it'll be okay (note that the log2 function in <cmath> will cast your integers to double):
std::cout << std::fixed;
std::cout << std::setprecision(16);
std::cout << static_cast<double>(274877906944) << std::endl;
std::cout << static_cast<double>(274877906942) << std::endl;
std::cout << static_cast<double>(274877906948) << std::endl;
std::cout << log2(274877906944) << std::endl;
std::cout << log2(274877906942) << std::endl;
std::cout<< log2(274877906948) << std::endl;
Produces:
274877906944.0000000000000000
274877906942.0000000000000000
274877906948.0000000000000000
38.0000000000000000
37.9999999999895053
38.0000000000209965
Demo
I just want to iterate through the members of an unordered map.
There are many simple examples on the web, including on this site, and yet none of them will compile. Apparently some examples are from a previous non-standard STL version, some are just old, and some are so new that my gcc 4.7.2 can't handle them. Please do not suggest the new auto iterator from C++11. I will get there some day when all my libraries are validated for that. Until then, I just want the old one to work. (see below for what I have tried)
Here is my test code:
#include <iostream>
#include <boost/unordered_map.hpp>
#include <string>
int main(int argc,char *argv[]) {
boost::unordered::unordered_map<std::string,int> umap;
//can't get gcc to accept the value_type()...
//umap.insert(boost::unordered_map::value_type("alpha",1));
//umap.insert(boost::unordered_map::value_type("beta",2));
//umap.insert(boost::unordered_map::value_type("gamma",3));
umap["alpha"]=1; //this works
umap["beta"]=2;
umap["gamma"]=3;
//can't get gcc to compile the iterator
//for (boost::unordered_map::iterator it=umap.begin();it!=umap.end();++it)
// std::cout << it->first <<", " << it->second << std::endl;
//gcc does not like it this way either
//for (int x=0;x<umap.size();x++)
// std::cout << x << " : " << umap[x].first << " = " << umap[x].second << std::endl;
//will gcc take this? No it does not
//for (int x=0;x<umap.size();x++)
// std::cout << x << " : " << umap[x] << std::endl;
//this does not work
//boost::unordered::unordered_map::iterator<std::string,int> it;
//this does not work
//boost::unordered::unordered_map::iterator it;
//for (it=umap.begin();it!=umap.end();++it)
// std::cout << it->first <<", " << it->second << std::endl;
//this does not work
//BOOST_FOREACH(boost::unordered_map::value_type value, umap) {
// std::cout << value.second;
// }
//std::cout << std::endl;
//this does not work either
//BOOST_FOREACH(boost::unordered_map::value_type<std::string,int> value, umap) {
// std::cout << value.second;
// }
//std::cout << std::endl;
std::cout << "umap size: " << umap.size() << std::endl;
std::cout << "umap max size: " << umap.max_size() << std::endl;
std::cout << "find alpha: " << (umap.find("alpha")!=umap.end()) << std::endl;
std::cout << "count beta: " << umap.count("beta") << std::endl;
}
Most of the errors are a variation of this:
error: 'template<class K, class T, class H, class P, class A> class boost::unordered::unordered_map' used without template parameters
Here is my build command:
g++ -I..\boost umap.cpp
I should be embarrassed for getting stuck on such a beginner's question, but from the volume of similar questions I am finding, this is just hard enough to stop a lot of people in their tracks. I have written hash containers before (back when it was recommended NOT to use STL) and I am very tempted to just write my own... but the right thing to do is learn to use as many existing tools as possible... help!
I've looked at the following questions on stackoverflow where I haven't found an answer:
iterate through unordered_map using boost_foreach
I tried:
BOOST_FOREACH(boost::unordered_map::value_type& value, umap) {
but it gives the same error I show below.
Unordered_map iterator invalidation
This one is close, but not quite my issue:
Iterator invalidation in boost::unordered_map
This one uses auto
and I can't switch compilers at this time.
C++ some questions on boost::unordered_map & boost::hash
This one is mostly about the theory of maps:
how to use boost::unordered_map
This is a rather complicated example, but you will see in my code I am already trying to declare iterators... they just won't compile.
How to use BOOST_FOREACH with an Unordered_map?
This is a nice example, but
it just does not compile. I tried a version of this in my code.
IT WORKS !
Here is the working code:
#include <iostream>
#include <boost/unordered_map.hpp>
#include <string>
int main(int argc,char *argv[]) {
boost::unordered::unordered_map<std::string,int> umap;
umap["alpha"]=1;
umap["beta"]=2;
umap["gamma"]=3;
boost::unordered::unordered_map<std::string,int>::iterator it;
for (it=umap.begin();it!=umap.end();++it)
std::cout << it->first <<", " << it->second << std::endl;
std::cout << "umap size: " << umap.size() << std::endl;
std::cout << "umap max size: " << umap.max_size() << std::endl;
std::cout << "find alpha: " << (umap.find("alpha")!=umap.end()) << std::endl;
std::cout << "count beta: " << umap.count("beta") << std::endl;
}
It was a syntax error. I was putting the type in the wrong place when declaring the iterator.
Thanks everyone for your responses.
try changing boost::unordered::unordered_map::iterator it; it to boost::unordered::unordered_map<std::string,int>::iterator it;
NOTE:
It is also possible, and a good idea in more complex situations, to create a typedef of it, such as typedef boost::unordered::unordered_map<std::string,int>::iterator UMapStringIntIt;, or whatever you may call it.
The answer is in the question, but the simple solution is here for your convenience:
#include <iostream>
#include <boost/unordered_map.hpp>
#include <string>
int main(int argc,char *argv[])
{
boost::unordered::unordered_map<std::string,int> umap;
umap["alpha"]=1;
umap["beta"]=2;
umap["gamma"]=3;
for ( auto it= umap.begin(); it != umap.end(); ++it )
std::cout << it->first <<", " << it->second << std::endl;
}
Can somebody please explain me how to enumerate a BOOST_ENUM using BOOST_FOREACH ?
The example below show that I got it to work with std::for_each, but not with BOOST_FOREACH.
Sample code :
BOOST_ENUM_VALUES( MyEnum,
const char *,
(xMin)("xMin")
(xMax)("xMax")
(yMin)("yMin")
(yMax)("yMax")
);
void blah(const MyEnum & val) // working demo with std_foreach
{
std::cout << "index=" << val.index() << " val=" << val.value() << " str=" << val.str() << std::endl;
}
void foo()
{
//BOOST_FOREACH : does not compile...
BOOST_FOREACH(MyEnum myEnum, MyEnum() ) // I tried to construct a "dummy" enum in order to use its iterator with no luck...
{
std::cout << "index=" << myEnum.index() << " val=" << myEnum.value() << " str=" << myEnum.str() << std::endl;
}
//std::for_each : works...
std::for_each(MyEnum::begin(), MyEnum::end(), blah);
}
Many thanks in advance!
Edit: as mentioned in the answer, the code does work with the newest codebase of boost.
Your example code above compiles and runs just fine for me with gcc 4.5.1 and vc2010 (after adding the corresponding #include's, that is). I tried with enum_rev4.6 from the vault. What compilation errors do you see?