1

問題のある例を使用しますが、トピックをできるだけ一般的なものに保つようにします. void (*)()を使用して入力パラメーターを取る別の関数からバインドしたいtype のパラメーターを取る関数がありますstd::bind。これはできますか?以下は、freeglut からの私の例です。

(私はこれを読みました:convert std::bind to function pointer、これは以下が機能しないことを確認します-回避策???)

void callback(Obj obj1, Obj obj2, Obj obj3)
{
  // do something with the object and display data
}

// meanwhile, in main()
std::function<void ()> callbackFunctor = &std::bind(callback, obj1, obj2, obj3);

// the following doesn't work because glutIdleFunc expects a type void (*)()
glutIdleFunc(callbackFunctor );

obj1obj2およびグローバルを作成する以外に、obj3通常、GLU​​T のアイドル コールバックに情報を渡すにはどうすればよいでしょうか?

4

2 に答える 2

1

グローバル (より良いstaticもの、1 つのファイルにのみ表示される)、折り畳まれた関数呼び出しにチェーンされる可能性があるか、呼び出し先関数内のset_/呼び出しなどを使用して別のシステム。get_userdata(function_address)

問題は、コールバックが常に同じパラメーターで呼び出される場合、なぜこの方法でそれらを渡したいのかということです。GLUT API にはこれがありません。

いずれにせよ、考えられるすべてのリクエストをカバーできる API はありません。何かが合わない場合は、何をしているのかを再考する必要があり、そうである場合は、指定された API の上に独自の回避策を実装する必要があります。

于 2013-10-28T06:08:14.663 に答える
1

std::functiona を関数ポインタに変換することはできません(逆にすることもできます)。

少し見回していたところ、バリアディックパックの保存方法に関するこの投稿を見つけました。

そのコードを少し変更してメンバーをstaticにすると、役に立つかもしれません。

namespace helper {
    template <std::size_t... Ts>
    struct index {};

    template <std::size_t N, std::size_t... Ts>
    struct gen_seq : gen_seq<N - 1, N - 1, Ts...> {};

    template <std::size_t... Ts>
    struct gen_seq<0, Ts...> : index<Ts...> {};
}

template <typename... Ts>
class Action {
private:
    static std::function<void (Ts...)> f_;
    static std::tuple<Ts...> args_;
public:
    template <typename F, typename... Args>
    static void setAction(F&& func, Args&&... args) {
        f_ = std::forward<F>(func);
        args_ = std::make_tuple(std::forward<Args>(args)...);
    }

    template <typename... Args, std::size_t... Is>
    static void func(std::tuple<Args...>& tup, helper::index<Is...>) {
        f_(std::get<Is>(tup)...);
    }

    template <typename... Args>
    static void func(std::tuple<Args...>& tup) {
        func(tup, helper::gen_seq<sizeof...(Args)>{});
    }

    static void act() {
        func(args_);
    }
};

// Init static members.
template <typename... Ts> std::function<void (Ts...)> Action<Ts...>::f_;
template <typename... Ts> std::tuple<Ts...> Action<Ts...>::args_;

上記のコードを使用すると、任意の関数または関数オブジェクトを実行時に指定された任意のパラメーターActionと共に格納し、パラメーターをとらないその静的メンバー関数を使用しact()て、以前に指定したパラメーターで格納された関数を呼び出すことができます。

act()変換可能なのでvoid (*)()、コールバック関数に渡すことができます。

以下が機能するはずです。

auto someCallable = [] (int x) { std::cout << "Number " << x << std::endl };
Action<int>::setAction(someCallable, 1); // Pass func and parameters.
glutIdleFunc(Action<int>::act);
于 2013-10-28T17:38:23.467 に答える