我个人不会将其改编为序列(我不确定您首先如何将其改编为二元素融合序列)。
不管它完成了,它都不会是通用的(所以你必须对不同类型的参数使用单独的改编(float
, double
, long double
, boost::multiprecision::number<boost::multiprecision::cpp_dec_float<50>>
etc.).
这似乎是 Spirit 的工作定制点 http://www.boost.org/doc/libs/1_55_0/libs/spirit/doc/html/spirit/advanced/customize.html:
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() };
}
};
} } }
现在你可以使用any std::complex<T>
具有期望融合序列的规则/表达式:
rule =
'(' << karma::double_ << ", " << karma::duplicate [ !karma::double_(0.0) << karma::double_ ] << ')'
| karma::double_ << karma::omit [ karma::double_ ];
注意如何
- I used
duplicate[]
to test for 0.0
在发出输出之前
- 在我使用的另一个分支上
omit
消耗虚部而不显示任何内容
这是一个完整的演示,住在科里鲁 http://coliru.stacked-crooked.com/a/bccb8b73ba706e6b
#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);
}
Output:
(123.0, 4.0)
123.0
(123.0, inf)
nan
(123.0, -1.0)