Compilation error with clang (result_of problem?)
Alexandre Hamez <[email protected]> Wed, 28 Nov 2012 16:54:31 +0100
| Newsgroups | gmane.comp.parsers.spirit.devel |
|---|---|
| Message-ID | <[email protected]> |
Hello,
Consider the following code (http://www.boost.org/doc/libs/1_52_0/libs/spirit/example/qi/mini_xml1.cpp modified):
/*****************************************************************************************************/
#include <string>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/qi.hpp>
namespace ascii = boost::spirit::ascii;
namespace qi = boost::spirit::qi;
namespace spirit = boost::spirit;
template <typename Iterator>
struct parser
: qi::grammar<Iterator, void(), qi::locals<std::string>, ascii::space_type>
{
qi::rule<Iterator, void(), qi::locals<std::string>, ascii::space_type> r_xml;
qi::rule<Iterator, std::string(), ascii::space_type> r_start;
qi::rule<Iterator, void(std::string), ascii::space_type> r_end;
parser()
: parser::base_type(r_xml)
{
using ascii::char_;
using ascii::string;
using qi::lexeme;
using qi::lit;
using namespace qi::labels;
r_start %= '<' >> !lit('/') >> lexeme[+(char_ - '>')] >> '>';
r_end = "</" >> string(_r1) >> '>';
r_xml = r_start[_a = _1] >> r_end(_a);
}
};
int main()
{
const std::string storage("<foo></foo>");
std::string::const_iterator iter = storage.begin();
const std::string::const_iterator end = storage.end();
const bool r = qi::phrase_parse(iter, end, parser<std::string::const_iterator>(), ascii::space);
return !(r && iter == end);
}
/*****************************************************************************************************/
When I try to compile this code with clang 4.1 (Apple clang version 4.1 (tags/Apple/clang-421.11.66) (based on LLVM 3.1svn)) and Boost 1.52, it fails with the message:
/opt/local/include/boost/spirit/home/qi/auxiliary/lazy.hpp:96:80: error: no type named 'type' in
'boost::result_of<boost::phoenix::actor<boost::phoenix::composite<boost::phoenix::detail::function_eval<1>,
boost::fusion::vector<boost::phoenix::value<boost::spirit::terminal<boost::spirit::tag::char_code<boost::spirit::tag::string,
boost::spirit::char_encoding::ascii>>>, boost::spirit::attribute<1>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_>>> (boost::spirit::unused_type,
boost::spirit::context<boost::fusion::cons<boost::spirit::unused_type &, boost::fusion::cons<std::__1::basic_string<char>, boost::fusion::nil>>,
boost::fusion::vector0<void>>)>'
typename boost::result_of<Function(unused_type, Context)>::type
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~
When I saw this message, I thought of the note related to the Boost 1.52 revision (http://www.boost.org/users/news/a_special_note_for_boost_1_52_0_and_higher.html) which warns about the change of boost::result_of. Thus, I tried with Boost 1.51, but it also fails, though with a different error message (/usr/bin/../lib/c++/v1/list:212:9: error: field has incomplete type 'boost::spirit::info').
Also, this problem seems related to the inherited attribute passed to the r_end rule. Whenever I remove anything related to this attribute, it compiles.
Finally, I should notice that it compiles with g++ 4.7.
So, is this a problem with Spirit or clang? And, whatever causes the problem, is there any possible workaround (keeping the inherited attribute)?
Regards,
--
Alexandre Hamez
------------------------------------------------------------------------------
Keep yourself connected to Go Parallel:
INSIGHTS What's next for parallel hardware, programming and related areas?
Interviews and blogs by thought leaders keep you ahead of the curve.
http://goparallel.sourceforge.net