首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Boost Karma -非消费谓词

Boost Karma -非消费谓词
EN

Stack Overflow用户
提问于 2014-04-15 09:06:06
回答 1查看 318关注 0票数 3

我需要打印一个std::复杂但省略虚设部分,如果它是等于零。所以我有两部作品的规则:

代码语言:javascript
复制
karma::rule<OutputIterator, std::complex<double>()> complexRule = 
    '(' << double_ << ", " double_ << ')'
    | double_ << omit[double_];

这样,业力总是会选择第一次生产,所以我需要某种谓词,它将产生一种分裂。助推业力教程附带了该解决方案,它要求将std::complex作为一个三元素元组进行调整。

代码语言:javascript
复制
BOOST_FUSION_ADAPT_ADT(
    std::complex<double>,
    (bool, bool, obj.imag() != 0, /**/)
    (double, double, obj.real(), /**/)
    (double, double, obj.imag(), /**/)
)

但不幸的是,我不能这样做,因为其他代码使用的是std::complex,作为两个元素元组。有没有办法解决这个问题而不直接将谓词添加到融合适配器中?

我试着用业力::eps发生器作为谓词

代码语言:javascript
复制
auto rule = eps( ... ) << '(' << double_ << ", " << double_ << ')'
          | double_ << omit[double_];

但是我不知道我应该在eps( . )中放什么凤凰表达式,而且由于Epsilon生成器不使用任何属性,所以我不确定是否可以从它访问std::complex?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-04-15 09:54:40

我个人不想把它作为一个序列来调整(我不知道你最初是如何把它作为一个双元素融合序列来调整的)。

无论如何,它将不是泛型的(因此您将对不同类型的参数(floatdoublelong doubleboost::multiprecision::number<boost::multiprecision::cpp_dec_float<50>>等)使用单独的适应)。

这似乎是圣灵的http://www.boost.org/doc/libs/1_55_0/libs/spirit/doc/html/spirit/advanced/customize.html的工作

代码语言:javascript
复制
namespace boost { namespace spirit { namespace traits {

    template <typename T>
        struct extract_from_attribute<typename std::complex<T>, boost::fusion::vector2<T, T>, void>
        {
            typedef boost::fusion::vector2<T,T> type;

            template <typename Context>
                static type call(std::complex<T> const& attr, Context& context)
                {
                    return { attr.real(), attr.imag() };
                }
        };

} } }

现在,您只需使用任何具有期望融合序列的规则/表达式的std::complex<T>

代码语言:javascript
复制
 rule = 
        '(' << karma::double_ << ", " << karma::duplicate [ !karma::double_(0.0) << karma::double_ ] << ')' 
      | karma::double_ << karma::omit [ karma::double_ ];

注意如何

  • 在发出输出之前,我使用duplicate[]测试0.0
  • 在另一个分支上,我使用omit来使用虚设部分,而不显示任何内容。

这是一个完整的演示,住在Coliru

代码语言:javascript
复制
#include <boost/spirit/include/karma.hpp>
#include <complex>

namespace boost { namespace spirit { namespace traits {

    template <typename T>
        struct extract_from_attribute<typename std::complex<T>, boost::fusion::vector2<T, T>, void>
        {
            typedef boost::fusion::vector2<T,T> type;

            template <typename Context>
                static type call(std::complex<T> const& attr, Context& context)
                {
                    return { attr.real(), attr.imag() };
                }
        };

} } }

namespace karma = boost::spirit::karma;

int main()
{
    karma::rule<boost::spirit::ostream_iterator, boost::fusion::vector2<double, double>()> 
        static const rule = 
                            '(' << karma::double_ << ", " << karma::duplicate [ !karma::double_(0.0) << karma::double_ ] << ')' 
                          | karma::double_ << karma::omit [ karma::double_ ];

    std::vector<std::complex<double>> const values {
                { 123, 4 },
                { 123, 0 },
                { 123, std::numeric_limits<double>::infinity() },
                { std::numeric_limits<double>::quiet_NaN(), 0 },
                { 123, -1 },
            };

    std::cout << karma::format_delimited(*rule, '\n', values);
}

输出:

代码语言:javascript
复制
(123.0, 4.0)
123.0
(123.0, inf)
nan
(123.0, -1.0)
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23079143

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档