C++ Boost::MPL fold example - wrong number of arguments - c++

I'd like to process some template arguments by using boost::mpl::fold. At the moment, I'm still stuck to the sample provided by Boost as even that does not work for me. I get the following error:
..\src\main.cpp:18:32: error: template argument 2 is invalid
..\src\main.cpp:18:37: error: wrong number of template arguments (4, should be 3)
The following code is taken from http://www.boost.org/doc/libs/1_48_0/libs/mpl/doc/refmanual/fold.html
#include <string>
#include <iostream>
#include <boost/mpl/fold.hpp>
#include <boost/mpl/plus.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/type_traits.hpp>
using namespace std;
using namespace boost;
using namespace boost::mpl;
using namespace boost::type_traits;
typedef vector<long,float,short,double,float,long,long double> types;
typedef fold<
types
, int_<0>
, if_< is_float<_2>,next<_1>,_1 >
>::type number_of_floats;
BOOST_MPL_ASSERT_RELATION( number_of_floats::value, ==, 4 );
int main(){
}
I'm running mingw 4.7.0 using the flag "-std=c++11". I found some other examples on the net but have not yet been successful in compiling anything useful. Any suggestions?

You are messing up the namespaces. Making a lot of symbols ambiguous.
Remove the using and the example works fine for me.
...
using namespace boost;
typedef mpl::vector<long,float,short,double,float,long,long double> types;
typedef mpl::fold<
types
, mpl::int_<0>
, mpl::if_< is_float<boost::mpl::_2>,boost::mpl::next<boost::mpl::_1>,boost::mpl::_1 >
>::type number_of_floats;
...

Related

boost::multiprecision::number

I'm new in using boost library, so I thanked every one that helps me.
#include "gmpxx.h"
#include <boost/multiprecision/gmp.hpp>
#include <boost/multiprecision/random.hpp>
#include <boost/multiprecision/number.hpp>
using namespace std;
using namespace boost::multiprecision;
using boost::multiprecision::mpz_int;
using boost::multiprecision::mpq_rational;
using boost::multiprecision::uint128_t;
using boost::multiprecision::uint256_t;
using boost::multiprecision::uint512_t;
using boost::multiprecision::uint1024_t;
using boost::multiprecision::mpf_float;
void testtmultiprecisions(){
mpq_rational b = boost::multiprecision::pow(mpf_float(1), mpf_float(2));
std::cout << typeid(b).name() << std::endl;
}
but i get compiler error like below :
error: conversion from boost::enable_if_c<true,
boost::multiprecision::detail::expression
<boost::multiprecision::detail::function,
boost::multiprecision::detail::pow_funct
<boost::multiprecision::backends::gmp_float<0u> >,
boost::multiprecision::number
<boost::multiprecision::backends::gmp_float<0u> >,
boost::multiprecision::number
<boost::multiprecision::backends::gmp_float<0u> >, void>
>::type {aka boost::multiprecision::detail::expression
<boost::multiprecision::detail::function,
boost::multiprecision::detail::pow_funct
<boost::multiprecision::backends::gmp_float<0u> >,
boost::multiprecision::number
<boost::multiprecision::backends::gmp_float<0u> >,
<boost::multiprecision::backends::gmp_float<0u> >, void>}
to non-scalar type â€کboost::multiprecision::mpq_rational {aka
boost::multiprecision::number
<boost::multiprecision::backends::gmp_rational,
(boost::multiprecision::expression_template_option)1u>}
requested
mpq_rational b = boost::multiprecision::pow(mpf_float(1), mpf_float(2));
i also changed above code :
mpq_rational b = boost::multiprecision::pow(mpf_float(1),
mpf_float(2)).covert_to<mpq_rational>();
and get new compiler errors :
[compiler error]
Rationals, by definition, have integral numerator and denominator.
Conversion of floating point to integral numbers is - again by definition - not lossless. The compiler will only compile conversions that are statically known to be lossless.
Also, conversions will not be chained (how would the library resolve ambiguous conversion paths?). In this case, you could help the compiler out using the intermediate step converting to the underlying type for mpq_rational (namely mpz_int):
#include <boost/multiprecision/gmp.hpp>
#include <boost/multiprecision/number.hpp>
#include <iostream>
using boost::multiprecision::mpq_rational;
using boost::multiprecision::mpz_int;
using boost::multiprecision::mpf_float;
int main() {
mpq_rational b = boost::multiprecision::pow(mpf_float(2), mpf_float(3)).convert_to<mpz_int>();
std::cout << b << "\n";
}
Prints
8

Boost Fusion compile error in VS 2013 RC

Hello I got the latest Boost from trunk which builds with VS 2013 RC. Built boost, it worked.
But when compiling my project against Boost, where I make use of Boost Fusion. I'm getting 100's of these error messages--
Error 1086 error C3520: 'T' : parameter pack must be expanded in this context
It refers to this code in make_vector10.hpp
namespace result_of
{
template <typename T0 , typename T1 , typename T2>
struct make_vector<T0 , T1 , T2>
{
typedef vector3<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type> type;
};
}
But there is no template parameter "T" used anywhere here.
This is also not a variadic template so I don't understand why it refers to parameter packs in the error message. "vector3" and "as_fusion_element" are also not variadic.
All variations of make_vector are giving me the same error btw(also make_set).
Anyone know what is going on here? Thanks
Here is a minimal repro
#include <boost/fusion/container.hpp>
#include <boost/fusion/algorithm.hpp>
#include <boost/fusion/include/algorithm.hpp>
#include <boost/fusion/sequence.hpp>
#include <boost/fusion/include/sequence.hpp>
#include <boost/fusion/support/pair.hpp>
#include <boost/fusion/include/pair.hpp>
namespace fs = boost::fusion;
namespace Key {
struct prep_table{}; struct draw_single{};
};
int main() {
fs::map<std::pair<Key::prep_table, float>, std::pair<Key::draw_single, int>> Blah;
return 0;
}
It was a compiler bug as reported by Felix Petroconi in the comments.
Work around: get latest boost, but roll back fusion to an earlier version

How am I supposed to write a metafunction that works like the ones in MPL?

I seem to be missing something when trying to write a meta-function that calls into MPL code. The follow code fails to compile with the following error on inst2, but works fine on inst1:
error C2903: 'apply' : symbol is neither a class template nor a function template
using namespace boost::mpl;
template <typename VECTOR>
struct first_element : mpl::at_c<VECTOR, 0> {};
int main()
{
typedef vector<
vector<int, int>,
vector<int, int>,
vector<int, int>> lotso;
typedef mpl::transform<lotso,
first_element<_1>>::type inst1;
typedef first_element<
at_c<lotso,0>>::type inst2;
return 0;
}
I think you forgot a ::type behind the call to at_c inside the typedef for inst2. Recall that your first_element expects something on which at_c can be applied. The raw at_c<lotso, 0>, however, is not yet evaluated. Evaluating a metafunction is done by adding ::type.
#include <boost/mpl/vector.hpp>
#include <boost/mpl/at.hpp>
#include <boost/mpl/transform.hpp>
#include <boost/mpl/placeholders.hpp>
#include <type_traits>
using namespace boost;
using namespace boost::mpl;
template <typename VECTOR>
struct first_element : mpl::at_c<VECTOR, 0> {};
int main()
{
typedef vector<
vector<int, int>,
vector<int, int>,
vector<int, int>> lotso;
typedef mpl::transform<lotso,
first_element<_1>>::type inst1;
typedef first_element<
at_c<lotso,0>::type >::type inst2;
^^^^^^ <--- you forgot a ::type here
static_assert(std::is_same<first_element<inst1>::type, inst2>::value, "bingo");
return 0;
}
Live Example. As a further check, I verified that a further dereference on inst1 gives the same type as inst2.

use Boost.Spirit.Qi to parse into vector

I am quite new to Spirit.
I am trying to use Qi to parse the argument for a CMD command in my embedded Tcl interpreter.
As some arguments may used multiple times, I will need a vector to store all arguments of the same sort.
This is a simplified example of my problem, where I try to store integers into a vector.
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_fusion.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
#include <boost/spirit/include/support.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/variant/recursive_variant.hpp>
using std::string;
using std::vector;
namespace {
namespace qi = boost::spirit::qi;
namespace phoenix = boost::phoenix;
namespace ascii = boost::spirit::ascii;
struct Argument {
vector<int> svDefine; // macro definitions
};
}
BOOST_FUSION_ADAPT_STRUCT
(
Argument,
(vector<int>, svDefine)
)
namespace {
typedef string::const_iterator SIter;
struct ArgParser : qi::grammar<SIter, Argument(), ascii::space_type> {
qi::rule<SIter, Argument(), ascii::space_type> start;
ArgParser() : ArgParser::base_type(start) {
using phoenix::at_c;
using qi::int_;
using phoenix::push_back;
using namespace qi::labels;
start = +("define" >> int_ [push_back(at_c<0>(_val), _1)]);
}
};
}
Compiling it with g++ 4.5.1 boost 1.51 generates lost of errors
In file included from /usr/include/boost/spirit/home/phoenix/container.hpp:10:0,
from /usr/include/boost/spirit/home/phoenix.hpp:12,
from /usr/include/boost/spirit/include/phoenix.hpp:13,
from qi_test.cpp:2:
.....
qi_test.cpp:43:64: instantiated from here
/usr/include/boost/spirit/home/phoenix/stl/container/container.hpp:492:40: error: ‘struct boost::fusion::vector<int>’ has no member named ‘push_back’
/usr/include/boost/spirit/home/phoenix/stl/container/container.hpp:492:40: error: return-statement with a value, in function returning 'void'
qi_test.cpp: In static member function ‘static
.....
qi_test.cpp:43:64: instantiated from here
qi_test.cpp:28:509: error: invalid initialization of reference of type boost::fusion::vector<int>&’ from expression of type ‘std::vector<int>’
Basically I am confused. No idea what is wrong.
You are mixing up two types of vector template classes here:
std::vector
and
boost::fusion::vector
if you just omit (comment out)
using std::vector;
things will probably become quite clear

How to apply an mpl::transform to an mpl::string?

I'm trying to apply a transformation to an mpl::string, but can't get it to compile. I'm using MS VC++2010 and Boost 1.43.0. The code:
#include <boost/mpl/string.hpp>
#include <boost/mpl/vector_c.hpp>
#include <boost/mpl/transform.hpp>
#include <boost/mpl/plus.hpp>
#include <boost/mpl/arithmetic.hpp>
using namespace boost;
int main() {
// this compiles OK
typedef mpl::vector_c<int, 'abcd', 'efgh'> numbers;
typedef mpl::transform<numbers, mpl::plus<mpl::_1, mpl::int_<1> > >::type result_numbers;
// this doesn't (error C2039: 'value' : is not a member of 'boost::mpl::has_push_back_arg')
typedef mpl::string<'abcd', 'efgh'> chars;
typedef mpl::transform<chars, mpl::plus<mpl::_1, mpl::int_<1> > >::type result_chars;
}
I've posted the full error message at http://paste.ubuntu.com/447759/.
The MPL docs say that mpl::transform needs a Forward Sequence, and mpl::string is a Bidirectional Sequence, which I gather is a type of Forward Sequence, so I thought it'd work.
Am I doing something wrong, or is this outright impossible? If so, why?
Thanks!
Turns out that it works if I use transform_view.