1
votes

I'm using Boost 1.57 with Visual Studio 2010.

I would like to upgrade my project to Visual Studio 2013 but i'm having some problem with the boost Spirit parser. Seem to me that the kwd parser is broken somehow. The following code compiles correctly in Visual Studio 2010:

#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/repository/include/qi_kwd.hpp>
#include <boost/spirit/repository/include/qi_keywords.hpp>
#include <iostream>
#include <string>
using boost::spirit::qi::double_;
using boost::spirit::qi::_1;
using boost::phoenix::ref;
using boost::spirit::repository::qi::kwd;

template <typename Iterator>
bool difference(Iterator first, Iterator last, double& n) {
    bool r = boost::spirit::qi::phrase_parse(first, last,
             //the grammar
             (kwd("A")[double_[ref(n) += _1]] /
              kwd("B")[double_ [ref(n) -= _1]]),
                              boost::spirit::ascii::space);
    if (first != last) return false;
    return r;
}

int main() {
    std::string str("A 1 B 2");
    double n=0;
    std::cout << "Full parse: " << difference(str.begin(), str.end(), n) << std::endl;  
    std::cout << "A - B = " << n <<std::endl;
    return 0;
}

The errors I get wnen i try to compile it with Visual Studio 2013 are (among the many):

 Error  3   error C3203: 'type' : unspecialized class template can't be used as a template argument for template parameter 'T2', expected a real type   ... fold_impl.hpp   
 Error  4   error C2039: 'type' : is not a member of 'boost::mpl::apply<boost::fusion::detail::apply_transform_result<boost::spirit::repository::qi::detail::string_keywords<Elements,boost::mpl::filter_view<Elements,boost::spirit::repository::qi::is_kwd_parser<boost::mpl::_>>,boost::mpl::filter_view<boost::mpl::vector2<boost::mpl::integral_c<T,0>,boost::mpl::integral_c<T,1>>,boost::spirit::repository::qi::keywords<Elements,Modifiers>::is_kwd_parser_filter<boost::mpl::_>>,boost::array<bool,2>,Modifiers>::build_char_type_sequence<StringKeywords>::element_char_type>,boost::spirit::repository::qi::kwd_parser<Subject,const char (&),boost::spirit::qi::make_directive_internal<T1,Subject,Modifiers,boost::mpl::false_>::iterator_type,boost::spirit::has_modifier<Modifiers,boost::spirit::tag::char_code_base<CharClass>>,Distinct>,boost::mpl::na,boost::mpl::na,boost::mpl::na,boost::mpl::na>'   ... value_of_impl.hpp   

Is this a bug of Boost? Is there any way to get this code to compile in Visual Studio 2013? (of course my real project is much bigger than this, it would be a problem to rewrite all the grammar)

Any help is appreciated.

1
It's certainly not MSVC specific. Here's clang stumbling (I removed the uses of namespaces that will introduce ambiguities that may silently wreak havoc). gcc does the same.sehe
I guess it is compiler version dependent: gcc 4.7.1 on my pc compiles it without a warning.Gab
indeed. See my answer explaining that :)sehe

1 Answers

2
votes

The problem appears to be that the mpl/fusion libraries have shifted to no longer expecting to TR1 result-of protocol.

This has everything to do with the fact that compilers at large have implemented decltype support, and in fact

  • BOOST_RESULT_OF_USE_DECLTYPE has become the default boost config for most compilers
  • Phoenix V3 has become the default for Spirit in recent versions

I verified that your particular sample does compile on clang when you insert this line at the top:

#define BOOST_RESULT_OF_USE_TR1

See it Live On Coliru

Actually this still represents a problem that should be reported to the Spirit mailing list, IMO as TR1 protocol will certainly be obsoleted in the future.

In the meantime, I suggest to use TR1 as a fallback only:

#define BOOST_RESULT_OF_USE_DECLTYPE_WITH_TR1_FALLBACK

See it Live On Coliru too.

NOTE

In order to compile with VS2013, I had to also add the following define

#define _SCL_SECURE_NO_WARNINGS

enter image description here