在 Visual Studio 2013 中提升 Spirit kwd 解析器

Posted

技术标签:

【中文标题】在 Visual Studio 2013 中提升 Spirit kwd 解析器【英文标题】:Boost Spirit kwd parser in Visual Studio 2013 【发布时间】:2014-11-25 11:59:52 【问题描述】:

我在 Visual Studio 2010 中使用 Boost 1.57。

我想将我的项目升级到 Visual Studio 2013,但我在使用 boost Spirit 解析器时遇到了一些问题。 在我看来, kwd 解析器以某种方式被破坏了。以下代码在 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;

我尝试使用 Visual Studio 2013 编译它时遇到的错误是(在众多错误中):

 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   

这是 Boost 的错误吗? 有没有办法让这段代码在 Visual Studio 2013 中编译? (当然我真正的项目比这个大很多,重写所有语法会是个问题)

感谢任何帮助。

【问题讨论】:

这当然不是 MSVC 特定的。这是clang stumbling(我删除了引入歧义的命名空间的使用,这些歧义可能会悄无声息地造成严重破坏)。 gcc does the same. 我猜它取决于编译器版本:我的电脑上的 gcc 4.7.1 编译它没有警告。 确实如此。请参阅我的答案解释:) 【参考方案1】:

问题似乎是 mpl/fusion 库已转变为不再期望 TR1 结果的协议。

这与编译器已经实现了 decltype 支持这一事实有关,事实上

BOOST_RESULT_OF_USE_DECLTYPE 已成为大多数编译器的默认 boost 配置 Phoenix V3 在最近的版本中已成为 Spirit 的默认设置

当您在顶部插入此行时,我验证了您的特定示例确实可以在 clang 上编译:

#define BOOST_RESULT_OF_USE_TR1

Live On Coliru

其实这仍然是一个应该向Spirit邮件列表报告的问题,IMO作为TR1协议将来肯定会被淘汰。

同时,我建议仅使用 TR1 作为后备:

#define BOOST_RESULT_OF_USE_DECLTYPE_WITH_TR1_FALLBACK

也看到 Live On Coliru

注意

为了用 VS2013 编译,我必须添加以下定义

#define _SCL_SECURE_NO_WARNINGS

【讨论】:

非常感谢,它确实有效。我会在 Boost 邮件列表中报告它,我一开始在文档中找不到解决方案,我(和你)花了一些时间来解决它。 对我来说,这与花费的时间无关。对我来说,这是关于未来验证此功能:) 感谢您的反馈

以上是关于在 Visual Studio 2013 中提升 Spirit kwd 解析器的主要内容,如果未能解决你的问题,请参考以下文章

Visual Studio 2013 OMP 发布模式

Visual Studio 需要在 Windows 7 中提升权限

提升Visual Studio 2015上的库

在两个 Visual Studio 实例中使用签名依赖项,一个提升/管理员,一个普通

Intel parallel studio 2017 集成在visual studio 2013 中,现在如何集成到visual studio 2015

(工作效率提升杂记) —— Visual Studio 效率提升类的的工具和设置(个人)