提升因果报应-非消耗谓词
Boost Karma - non consuming predicate
我需要打印一个std::复数,但如果它等于零,则省略虚部。所以我有一个关于两个产品的规则:
karma::rule<OutputIterator, std::complex<double>()> complexRule =
'(' << double_ << ", " double_ << ')'
| double_ << omit[double_];
这样因果报应总是会选择第一个结果,所以我需要某种谓词来做出决定。Boost Karma教程附带了该解决方案,该解决方案需要将std::complex调整为三元素元组。
BOOST_FUSION_ADAPT_ADT(
std::complex<double>,
(bool, bool, obj.imag() != 0, /**/)
(double, double, obj.real(), /**/)
(double, double, obj.imag(), /**/)
)
但不幸的是,我无法做到这一点,因为其他代码使用std::complex作为两元素元组。有没有一种方法可以在不将谓词直接添加到Fusion适配器中的情况下解决这个问题?
我试图使用因果报应::eps生成器作为谓词
auto rule = eps( ... ) << '(' << double_ << ", " << double_ << ')'
| double_ << omit[double_];
但我不知道我应该在eps(…)中放入什么Phoenix表达式,而且由于Epsilon Generator不消耗任何属性,我不确定是否可以从中访问std::complex?
我个人不会将其改编为序列(我不确定你最初是如何将其改编成两元素融合序列的)。
不管怎样,它都不会是通用的(所以你必须对不同类型的参数(float
、double
、long double
、boost::multiprecision::number<boost::multiprecision::cpp_dec_float<50>>
等)使用单独的适应
这似乎是Spirit的定制点:的工作
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>
和期望融合序列的规则/表达式:
rule =
'(' << karma::double_ << ", " << karma::duplicate [ !karma::double_(0.0) << karma::double_ ] << ')'
| karma::double_ << karma::omit [ karma::double_ ];
注意
- 在发出输出之前,我使用
duplicate[]
对0.0
进行测试 - 在另一个分支上,我使用
omit
来消耗虚部,而不显示任何内容
这是一个完整的演示,在Coliru上直播
#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);
}
输出:
(123.0, 4.0)
123.0
(123.0, inf)
nan
(123.0, -1.0)
相关文章:
- std::condition_variable::wait()如何评估给定的谓词
- 有没有办法将谓词中的元素偏移量传递给 std 算法?
- 如何在 STL 函数中找到传递给谓词的元素的索引?
- 为 C++11 算法组合多个谓词
- 处理 std::enable_if<...中谓词的逻辑"OR">
- std::map与谓词与初始化列表
- 尝试使用谓词函数会导致错误:"std::sort"未找到匹配的重载函数
- 如何有效地操作满足给定谓词的向量中的所有项目?
- 排序谓词没有传递对索引对象的引用?
- 将 unordered_map 与 Catch2 谓词一起使用时类型不匹配
- 提升::精神::因果报应使用有条件的替代操作符(|)
- 使用因果报应生成指针向量的输出
- 在提升精神因果报应中,如何可能将属性传递给子规则
- 当一个规则使用BOOST_FUSION_ADAPT_STRUCT时,精神因果报应语法问题
- 提升因果报应-从一个属性生成多个字符串
- 提升:精神:因果报应:如何获得输出的当前位置
- C++助推::精神::因果报应规则的变体
- 语义演员的助推::精神::因果报应::发光
- 提升::精神::因果报应基于输入属性的替代选择
- 提升因果报应-非消耗谓词