9

타사 함수를 통해 다른 메서드를 호출하려고합니다. 둘 다 variadic 템플릿을 사용합니다. 예를 들어 :std :: bind(), variadic templates 및 완벽한 전달 방법을 결합하는 방법은 무엇입니까?

void third_party(int n, std::function<void(int)> f) 
{ 
    f(n); 
} 

struct foo 
{ 
    template <typename... Args> 
    void invoke(int n, Args&&... args) 
    { 
    auto bound = std::bind(&foo::invoke_impl<Args...>, this, 
          std::placeholders::_1, std::forward<Args>(args)...); 

    third_party(n, bound); 
    } 

    template <typename... Args> 
    void invoke_impl(int, Args&&...) 
    { 
    } 
}; 

foo f; 
f.invoke(1, 2); 

문제는, 내가 컴파일 오류 얻을 :

/usr/include/c++/4.7/functional:1206:35: error: cannot bind ‘int’ lvalue to ‘int&&’ 
내가 람다를 사용하여 시도

하지만 GCC 4.8은 아직 구문을 처리하지 않습니다 maybe을; 여기에 내가 뭘하려 :

auto bound = [this, &args...] (int k) { invoke_impl(k, std::foward<Args>(args)...); }; 

내가받을 다음과 같은 오류 : 내가 생각하는 동안, 컴파일러, 유형 int&&invoke_impl의 인스턴스를 원하는 이해하는 것과

error: expected ‘,’ before ‘...’ token 
error: expected identifier before ‘...’ token 
error: parameter packs not expanded with ‘...’: 
note:   ‘args’ 

이이 경우에 &&를 사용하여 실제 인수 형식을 유지합니다.

내가 뭘 잘못하고 있니? 감사,

+0

GCC 4.8은 구문을 완벽하게 처리합니다. 너 무슨 짓을 한거야? –

+0

@ArneMertz 내가 시도한 구문으로 질문을 업데이트했습니다. – piwi

+0

gcc에서 방금 버그가 발생한 것 같습니다. http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41934 –

답변

6

&foo::invoke_impl<Args...>에 바인딩하면 Args&& 매개 변수, 즉 rvalue를 사용하는 바운드 함수가 만들어집니다. 문제는 전달 된 매개 변수가 왼쪽 값 일 것입니다. 왜냐하면 인수가 내부 클래스의 멤버 함수로 저장되기 때문입니다.

수정하려면 &foo::invoke_impl<Args...>&foo::invoke_impl<Args&...>으로 변경하여 참조 축소 규칙을 사용하여 멤버 함수가 왼쪽 값을 갖도록합니다.

auto bound = std::bind(&foo::invoke_impl<Args&...>, this, 
         std::placeholders::_1, std::forward<Args>(args)...); 

Here is a demo.

+0

사실, 이 솔루션은'std :: reference_wrapper'를 인수로 사용하면 작동하지 않습니다. 여기에 예제가 있습니다 : http://ideone.com/VBxfZd; 참조 래퍼 사용과 관련하여 누락 된 것이 있습니까? – piwi

+0

@piwi 그런 다음'Args & ...'를'Args const & ...'로 변경하십시오. 왜 그것이 비록 작동하는지 완전히 모릅니다. – 0x499602D2

+0

내 잘못, 나는 이것을 가지고 올 수 있었다 ;-) 고마워. – piwi

관련 문제