2010-04-29 4 views
9

C++ 0x 기능 중 일부를 이해하기위한 개인적인 실험 중 하나 : 실행할 함수 파일 포인터에 함수 포인터를 전달하려고합니다. 결국 실행은 다른 스레드에서 발생합니다. 그러나 모든 다른 유형의 기능을 사용하면 템플릿을 사용할 수 없습니다.템플릿, 함수 포인터 및 C++ 0x

#include <functional> 

int foo(void) {return 2;} 

class bar { 
public: 
    int operator() (void) {return 4;}; 
    int something(int a) {return a;}; 
}; 

template <class C> 
int func(C&& c) 
{ 
    //typedef typename std::result_of< C() >::type result_type; 
    typedef typename std::conditional< 
     std::is_pointer<C>::value, 
     std::result_of< C() >::type, 
     std::conditional< 
      std::is_object<C>::value, 
      std::result_of< typename C::operator() >::type, 
      void> 
     >::type result_type; 
    result_type result = c(); 
    return result; 
} 

int main(int argc, char* argv[]) 
{ 
    // call with a function pointer 
    func(foo); 

    // call with a member function 
    bar b; 
    func(b); 

    // call with a bind expression 
    func(std::bind(&bar::something, b, 42)); 

    // call with a lambda expression 
    func([](void)->int {return 12;}); 

    return 0; 
} 

result_of 템플릿 혼자 클래스 바, 내가 컴파일되지 않습니다 만든 투박한 조건에서 연산자()를 찾을 수있을 것 같지 않습니다. 어떤 아이디어? const 함수에 추가 문제가 있습니까?

+0

아마도'func'가'result_type' 대신에'int'를 리턴하기 때문입니다 (이 예제에서는 모든 경우에'int'이지만 여전히 문제를 일으킬 수 있습니다)? –

+0

@Chris : 아니, 그게 이유가 아니야. – kennytm

+0

@KennyTM - 나는 생각하지는 않지만 여전히 문제라고 생각합니다. –

답변

6

decltype 어때요? 내가 C + +0 초안을 이해한다면

template <class C> 
auto func(C&& c) -> decltype(c()) { 
    auto result = c(); 
    return result; 
} 
+0

훨씬 깨끗해 보입니다. 감사! – user328543

4

오른쪽 실제로 충분해야 다음

typedef typename std::result_of<C()>::type result_type; 

그 대신 조건식의 사용, 그것은 gcc4.5에 잘 컴파일 - 어쩌면 당신은 어떤 컴파일러에서 버그를 발견 했나요?

+0

그게 너무 생각했는데 컴파일되지 않았어. 복잡한 조건부 전체가이를 해결하기 위해 만들어졌습니다. – user328543

+1

@ user328543 : 조건문을 주석 처리하고 이전에 주석 처리 된 행을 gcc4.5에서 절대적으로 잘 컴파일하면됩니다. –

2

템플릿을 인스턴스화 할 수 있지만 GCC는 result_of을 사용할 때마다 불만을 토로합니다.

template <class C> 
int func(C&& c) 
{ 
    //typedef typename std::result_of< C() >::type result_type; 
    typedef typename std::conditional< 
     std::is_pointer<C>::value, 
     // C++0x still requires "typename" sprinkles: 
     typename std::result_of< C() >::type, 
     typename std::conditional< 
      std::is_object<C>::value, 
      // result_of takes a *type* as an argument, not an object: 
      //typename std::result_of< decltype(&C::operator()) >::type, 
      // Or better: 
      typename std::result_of<C>::type, 
      void> 
     >::type result_type; 
    result_type result = c(); 
    return result; 
} 

int main(int argc, char* argv[]) 
{ 
    // according to GCC, func(foo) passes a function reference. 
    func(foo); 

첫 번째 오류 메시지 :

rof.cpp:23:17: error: invalid use of incomplete type 'struct std::result_of<int (&)()>' 

result_of이 표준에 지정된대로 구현, 그래서 GCC는 부분 특수화 선언에 의사 프로토 타입 구문과 일치하지 수 있다는 것을 나타납니다.

+0

함수에 대한 참조가 작동해야합니다. * "Fn은 함수 객체 유형 (20.8), 함수 참조 또는 함수 객체 유형에 대한 참조"가되어야합니다. * –

+1

@gf : 멋지군. 어느 쪽이든, GCC의 오류 메시지는 명확하게 그것이 좋은 코드를 거부하고 있음을 보여줍니다. – Potatoswatter

+0

@gf : 잘못된 스레드입니까? – Potatoswatter