2

編集:これは一時的な問題であることが判明しました。基本的に、私はC ++をJavaやC#のように機能するかのように無意識のうちに使用していましたが、そうではありません。うまくいけば、これは良い注意話になるでしょう。

joint_view編集:この問題は、との組み合わせでのみ発生するようshared_ptrです。生のポインターは同じシナリオで正常に機能するように見えます。これは、すべてのアイテムを同時に追加せずに構築されたプレーンなフュージョンコンテナー内の共有ポインターと同様です。以下の詳細:

mingw gcc 4.5.1を 使用しています。ブーストフュージョンコンテナを使用してコンテンツを元に戻すときに、特有の問題が発生します。にラップされたカスタムクラスがありstd::shared_ptr、それがフュージョンに渡されますmake_list()(またはmake_vector()、問題ではないようです)。すべてのオブジェクトを一度にコンテナに入れることができれば、すべてうまくいきます。コンテナに別の共有ポインタを追加すると、問題が発生するようです。これにより、が生成されますjoint_view。を使用して繰り返しfusion::for_each()、関数オブジェクトを渡して値を出力します。、の代わりに共有ポインターのプレーンな融合コンテナーを反復している場合joint_view、または共有ポインターが含まjoint_viewれていない場合は正常に機能しますが、それ以外の場合は、セグメンテーション違反またはガベージ値です。

以下は、問題を特定するために作成したテストプログラムです。問題が何であるかについてのアイデアはありますか?やるべき/やるべきでないことを見逃している可能性は十分にあります:(

#include <iostream>
#include <memory>

//BOOST SMART POINTERS
//I only use boost's shared_ptr for ONE test, results are the same.
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>

//BOOST FUSION
#include <boost/fusion/algorithm/iteration/for_each.hpp>
#include <boost/fusion/include/for_each.hpp>
#include <boost/fusion/container/generation/make_list.hpp>
#include <boost/fusion/include/make_list.hpp>
#include <boost/fusion/container/generation/make_vector.hpp>
#include <boost/fusion/include/make_vector.hpp>
#include <boost/fusion/algorithm/transformation/push_back.hpp>
#include <boost/fusion/include/push_back.hpp>

using namespace std;
using namespace boost::fusion;

struct TestStructInt {
    int test_int;

    TestStructInt(int init_num) : test_int(init_num) {};
};

struct TestStructString {
    string test_string;

    TestStructString(string init_str) : test_string(init_str) {};
};

struct do_junk{
    void operator()(string t) const {
        cout << t << endl;
    }

    void operator()(string* t) const {
        cout << *t << endl;
    }

    void operator()(std::shared_ptr<int> t) const {
        cout << *t << endl;
    }

    void operator()(std::shared_ptr<string> t) const {
        cout << *t << endl;
    }

    void operator() (boost::shared_ptr<string> t) const {
        cout << *t << endl;
    }

    void operator() (TestStructInt t) const {
        cout << t.test_int << endl;
    }

    void operator() (std::shared_ptr<TestStructInt> t) const {
        cout << t->test_int << endl;
    }

    void operator() (TestStructString t) const {
        cout << t.test_string << endl;
    }

    void operator() (std::shared_ptr<TestStructString> t) const {
        cout << t->test_string << endl;
    }

    void operator() (std::shared_ptr<TestStructString*> t) const {
        cout << (*t)->test_string << endl;
    }
};

int main()
{
    string foo1 = "foo1";
    string foo2 = "foo2";
    string foo3 = "foo3";
    int bar1 = 1;
    int bar2 = 2;
    int bar3 = 3;
    string* foo1_ptr = &foo1;
    string* foo2_ptr = &foo2;
    string* foo3_ptr = &foo3;
    auto foo1_obj = make_shared<TestStructString>(TestStructString("foo1"));
    auto foo2_obj = make_shared<TestStructString>(TestStructString("foo2"));
    auto foo3_obj = make_shared<TestStructString>(TestStructString("foo3"));

    //works fine
    auto list_test1 = make_list(foo1, foo2);

    //works fine
    auto list_test2 = make_list(foo1_ptr, foo2_ptr);

    //seems to work, but is undefined behavior
    auto list_test3
        = make_list(
            std::make_shared<int>(bar1), std::make_shared<int>(bar2)
        )
    ;

    //seems to work, but is undefined behavior
    auto list_test4
        = make_list(
            std::make_shared<string>(foo1), std::make_shared<string>(foo2)
        )
    ;

    //seems to work, but is undefined behavior
    auto list_test5
        = make_list(
            std::make_shared<TestStructInt>(TestStructInt(1))
            , std::make_shared<TestStructInt>(TestStructInt(2))
        )
    ;

    //seems to work, but is undefined behavior
    auto list_test6
        = make_list(
            std::make_shared<TestStructString>(TestStructString("foo1"))
            , std::make_shared<TestStructString>(TestStructString("foo2"))
        )
    ;

    //seems to work, but is undefined behavior
    auto list_test7
        = make_list(TestStructString("foo1"), TestStructString("foo2"))
    ;

    //seems to work, but is undefined behavior
    auto joint_view_test1 = push_back(make_list(foo1, foo2), foo3);

    //seems to work, but is undefined behavior
    auto joint_view_test2 = push_back(make_list(foo1_ptr, foo2_ptr), foo3_ptr);

    //seems to work, but is undefined behavior
    auto joint_view_test3
        = push_back(
            make_list(
                TestStructString(foo1), TestStructString(foo2)
            )
            , TestStructString(foo3)
        )
    ;

    //integer values I pass in are coming out different
    auto joint_view_test4
        = push_back(
            make_list(
                std::make_shared<int>(bar1), std::make_shared<int>(bar2)
            )
            , make_shared<int>(bar3)
        )
    ;

    //pass in foo1, foo2, and foo3, but only get foo3's value back out for each
    auto joint_view_test5
        = push_back(
            make_list(
                std::make_shared<string>(foo1), std::make_shared<string>(foo2)
            )
            , make_shared<string>(foo3)
        )
    ;

    //causes seg fault when running do_junk()
    auto joint_view_test6
        = push_back(
            make_vector(
                std::make_shared<string>(foo1), std::make_shared<string>(foo2)
            )
            , std::make_shared<string>(foo3)
        )
    ;

    //causes seg fault when running do_junk()
    auto joint_view_test7
        = push_back(
            make_list(
                boost::make_shared<string>(foo1)
                , boost::make_shared<string>(foo2)
            )
            , boost::make_shared<string>(foo3)
        )
    ;

    //integer values I pass in are coming out different
    auto joint_view_test8
        = push_back(
            make_list(
                std::make_shared<TestStructInt>(TestStructInt(1))
                , std::make_shared<TestStructInt>(TestStructInt(2))
            )
            , std::make_shared<TestStructInt>(TestStructInt(3))
        )
    ;

    //causes seg fault when running do_junk()
    auto joint_view_test9
        = push_back(
            make_list(
                std::make_shared<TestStructString>(TestStructString("foo1"))
                , std::make_shared<TestStructString>(TestStructString("foo2"))
            )
            , std::make_shared<TestStructString>(TestStructString("foo3"))
        )
    ;

    //causes seg fault when running do_junk()
    auto joint_view_test10
        = push_back(
            make_list(
                std::make_shared<TestStructString*>(new TestStructString("foo1"))
                , std::make_shared<TestStructString*>(new TestStructString("foo2"))
            )
            , std::make_shared<TestStructString*>(new TestStructString("foo3"))
        )
    ;

    //seems to work, but is undefined behavior
    auto joint_view_test11
        = push_back(
            make_list(
                foo1_obj
                , foo2_obj
            )
            , foo3_obj
        )
    ;

    cout << "@@ list1" << endl;
    boost::fusion::for_each(list_test1, do_junk());
    cout << "@@ list2" << endl;
    boost::fusion::for_each(list_test2, do_junk());
    cout << "@@ list3" << endl;
    boost::fusion::for_each(list_test3, do_junk());
    cout << "@@ list4" << endl;
    boost::fusion::for_each(list_test4, do_junk());
    cout << "@@ list5" << endl;
    boost::fusion::for_each(list_test5, do_junk());
    cout << "@@ list6" << endl;
    boost::fusion::for_each(list_test6, do_junk());
    cout << "@@ list7" << endl;
    boost::fusion::for_each(list_test7, do_junk());
    cout << "@@ joint_view1" << endl;
    boost::fusion::for_each(joint_view_test1, do_junk());
    cout << "@@ joint_view2" << endl;
    boost::fusion::for_each(joint_view_test2, do_junk());
    cout << "@@ joint_view3" << endl;
    boost::fusion::for_each(joint_view_test3, do_junk());
    cout << "@@ joint_view4" << endl;
    boost::fusion::for_each(joint_view_test4, do_junk());
    cout << "@@ joint_view5" << endl;
    //boost::fusion::for_each(joint_view_test5, do_junk());
    cout << "@@ joint_view6" << endl;
    //boost::fusion::for_each(joint_view_test6, do_junk());
    cout << "@@ joint_view7" << endl;
    //boost::fusion::for_each(joint_view_test7, do_junk());
    cout << "@@ joint_view8" << endl;
    //boost::fusion::for_each(joint_view_test8, do_junk());
    cout << "@@ joint_view9" << endl;
    //boost::fusion::for_each(joint_view_test9, do_junk());
    cout << "@@ joint_view10" << endl;
    //boost::fusion::for_each(joint_view_test10, do_junk());
    cout << "@@ joint_view11" << endl;
    boost::fusion::for_each(joint_view_test11, do_junk());
    cout << "@@" << endl;

    return 0;
}
4

2 に答える 2

4

fusion::joint_viewその要素を参照として保持しています。一時変数を参照しないように十分に注意する必要があります (設定の繰り返し時に範囲外になる可能性があります)。これはあなたの例に当てはまるようです。

于 2010-10-14T12:39:56.773 に答える
0

私はサンプルからそれがあなたがしていることだと100%確信しているわけではありませんが、通常、反復中にリストの内容を変更することはできません。そうでなければ、イテレータが無効です。追加するアイテムのリストをキューに入れ、最後に一度にすべて追加します。

于 2010-10-13T17:46:44.537 に答える