1

次の問題があります: real_p パーサーを使用して実数を解析する古いコードを再利用しています。各数値をキャプチャして文字列に変換し、文字列のベクトルに入れたいと思います。次のコードを使用しています。ここで、l_double は double 型の変数で、convertdouble 関数は double を文字列に変換し、result.m_literalValues は文字列のベクトルです。ただし、コードは解析された値を l_double に割り当てません。

rule<> alternative3 =   +(real_p        [assign_a(l_double)]
                                        [push_back_a(result.m_LiteralValues, convertdouble(l_double))]
                                        >>  str_p(",")
                            )

誰かが私が間違っていることを知っていますか?

注: 例よりもはるかに複雑な古いコードを再設計するつもりはありません。解析されたすべての値の文字列を抽出し、それらを文字列のベクトルに入れたいだけです。

4

1 に答える 1

1

問題はpush_back_a(result.m_LiteralValues, convertdouble(l_double))、具体的には にあるようconvertdouble(l_double)です。2 番目の引数は、「ポリシー ホルダー アクター」に格納される参照であるpush_back_a必要があるため、そこで関数呼び出しを使用するとエラーが発生します。保存する必要がなくl_double、単に一時的に使用していた場合、目的を達成する 1 つの方法は、ここでpush_back_a説明されているのと同様に動作する独自のフェニックス関数を作成することです(完全な例はこちら)。次のようにフェニックス関数を定義します。

struct push_back_impl
{
    template <typename Container, typename Item>
    struct result
    {
        typedef void type;
    };

    template <typename Container, typename Item>
    void operator()(Container& c, Item const& item) const
    {
        c.push_back(convertdouble(item));
    }
};

function<push_back_impl> const push_back = push_back_impl();

次に、次のようにルールを定義します。

rule<> alternative3 =   +( real_p[push_back(var(result.m_LiteralValues),arg1)] >>  str_p(",") );

完全にコンパイル可能なコード (c++ 11 を使用できない/使用したくない場合は、for ループを変更して結果を表示します):

#include <boost/spirit/include/classic_core.hpp>
#include <boost/spirit/include/classic_operators.hpp>
#include <boost/spirit/include/phoenix1_functions.hpp>
#include <boost/spirit/include/phoenix1_primitives.hpp>
#include <iostream>
#include <string>
#include <sstream>
#include <vector>

using namespace boost::spirit::classic;
using namespace phoenix;

std::string convertdouble(const double& d)
{   
    std::stringstream ss;
    ss<<d;
    return ss.str();
}

struct push_back_impl
{
    template <typename Container, typename Item>
    struct result
    {
        typedef void type;
    };

    template <typename Container, typename Item>
    void operator()(Container& c, Item const& item) const
    {
        c.push_back(convertdouble(item));
    }
};

function<push_back_impl> const push_back = push_back_impl();

struct Results
{
    std::vector<std::string> m_LiteralValues;
};


int main()
{
    Results result;
    char const* test="2.5,3.6,4.8,";
    rule<> alternative3 =   +( real_p[push_back(var(result.m_LiteralValues),arg1)] >>  str_p(",") );

    if(parse(test,alternative3,space_p).full)
    {
        std::cout << "success" << std::endl;
        for(auto& str :result.m_LiteralValues)
            std::cout << str << std::endl;
    }
    else
    {
        std::cout << "failure" << std::endl;
    }

    return 0;                       
}
于 2013-01-11T12:36:28.447 に答える