2013-10-28 2 views
1

나는 문제가있는 예제를 사용할 것이지만 가능한 한 일반적인 주제로 유지하려고 노력할 것이다. 나는 std::bind을 사용하여 입력 매개 변수를 취하는 다른 함수에서 바인드하려는 void (*)() 유형의 매개 변수를 사용하는 함수가 있습니다. 이 작업을 수행 할 수 있습니까? obj1, obj2obj3 전역을 제외하고전역을 사용하지 않고 함수 포인터 콜백에 정보를 전달할 수 있습니까?

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); 

- (해결 방법을 상기 다음이 작동하지 않는 것을 확인 convert std::bind to function pointer, 내가이 글을 읽을했다)

: 아래 freeglut에서 내 예입니다 , 어떻게 정상적으로 GLUT의 유휴 콜백에 정보를 전달합니까?

답변

1

std::function기능 포인터으로 변환 할 수 없습니다 (반대 작업을 수행 할 수 있음).

나는 약간 주위를 둘러 보았고 variadic 팩을 저장하는 방법에 대해 this post을 찾았습니다. 회원 정적

당신이 그 코드를 조금 수정하면

, 그것은 당신에게 유용 할 수 있습니다

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); 
1

전역 (예 : 하나의 파일에만 표시), 접힌 함수 호출로 연결될 수 있습니다. set_/get_userdata(function_address) 호출 수신자 함수 내에서 호출.

항상 같은 매개 변수를 사용하여 콜백을 호출하는 경우 질문은 왜 이러한 방식으로 전달하려고합니까? GLUT API는 아무 쓸모가 없기 때문에 이것을 가지고 있지 않습니다.

어떤 방법으로도 API는 가능한 모든 요청을 처리 할 수 ​​없습니다. 무언가가 맞지 않으면, 무엇을하고 있는지 다시 생각해 봐야하고, 확실하다면, 주어진 API를 바탕으로 자신 만의 해결책을 구현하십시오.

관련 문제