2009-10-25 4 views
3

main 외부에서 foo_를 전달할 방법이 있습니까? 나는 Functor에 관한 또 다른 질문에서 Boost에 관해 뭔가를 보았다. 그게 효과가있을 것 같습니다. 그 질문에 부스트가 언급 된 answer가 있습니다. 가능한 경우 부스트를 피하고 싶습니다.중첩 된 functor (C++) 전달하기

#include <iostream> 

int main() 
{ 
    class foo { 
     public: 
     void operator()() { 
      std::cout << "Hello" << std::endl; 
     } 
    }; 

    foo foo_; 
    foo_(); 
    return 0; 
} 

답변

4

아니요, 현재 로컬 유형은 템플릿으로 들어갈 수 없습니다 (그렇지 않으면 boost 또는 std :: tr1 :: function 사용). 그러나 Foo가 무언가를 상속하는 곳 (즉, foo가 구현 한 가상 opeator() func을 가짐)과 Foo에 대신 ptr을 전달하면 OOP을 수행 할 수 있습니다.

+0

'boost :: function'을 템플릿 매개 변수로 사용하는 것은 호출 할 수있는 것이 아니라 일반적인 호환 가능한 함수 프로토 타입입니다. 'foo'에 대해서는'void()'가 될 것입니다 - 인자를 취하지 않고 아무것도 반환하지 않는 함수의 서명. – sbi

+0

@sbi : 시도해 보셨습니까? 'function'의 생성자는 여전히 템플릿이 될 것이고, 여전히 로컬 타입을 템플릿 매개 변수로 사용해야 할 것입니다. – UncleBens

+0

@sbi : 'foo :: operator() '의 주소를 가져 가면 작동하지만 'boost :: function'에 Foo 객체를 저장할 수 없습니다. – Macke

0

EDIT : 일부 복사기가 불만없이 조치를 취하더라도 올바른 C++로 표시되지 않습니다.

functor를 템플릿 매개 변수로 받아들이는 무언가가 있다면 잘 모르겠지만 Functor로 행동하는 것은 무엇이든 통과시킬 수 있습니까?

template< class tFunctor > 
void UseFunctor(const tFunctor& func) 
{ 
    func(); 
} 

int main() 
{ 
    foo foo_; 
    UseFunctor(foo_); 
} 
+0

'func'은 _const'_ 참조이며, Scott의'operator()()'는'const'가 아닙니다. 가능한 경우 함수 호출 연산자'const'를 만들 것을 권장합니다. 그러나 std lib의 방법은 함수 객체를 복사하는 것이 싸고'const' 템플릿을 사용하는 것이 결코 부담스럽지 않다고 가정하는 것입니다. void UseFunctor (Func uunc)'. – sbi

0

현재 범위에서 정의되지 않은 클래스 멤버를 호출 할 수 없다고 생각합니다. 이 경우 함수 작성기는 상태를 유지하지 않고 매개 변수를 사용하지 않고 값을 반환하지 않는 함수처럼 동작하므로 원시 함수 포인터에 인스턴스를 지정할 수 있습니다. 그러나 더 이상은 foo이 아니며 함수 포인터 일뿐입니다.

class base 
{ 
public: 
    void operator()() { doit(); } 
protected: 
    virtual void doit() = 0; 
}; 

int main() 
{ 
    class foo 
    { 
    public: 
     void operator()() { doit(); } 
    protected: 
     virtual void doit() 
     { 
      std::cout << "Hello" << std::endl; 
     } 
    }; 
} 

이제 foo는의 인스턴스를 전달 주위 기본, 같은 수 있습니다 :

하나의 솔루션과 같은 글로벌 범위에서 정의 된 순수 가상 기본 클래스에서 foo는을 유도하는 것입니다 가상 doit() 메서드가 예상대로 호출됩니다.

+0

"현재 범위에서 정의되지 않은 클래스의 멤버를 호출 할 수 없다고 생각합니다." 그건 말도 안돼. 함수 객체가있을 때마다 현재 범위에서 정의 된 클래스의 멤버 함수를 호출하는 경우는 거의 없습니다.(함수 객체를'std :: for_each()'에 건네 주면, 그 함수의'operator()'가 호출됩니다 만, 그 범위에서는 확실히 정의되지 않습니다.) – sbi

+0

@sbi - 직접 문제는 아닙니다 operator()를 호출하지만 foreach를 호출하면됩니다. 다음과 같은 경우 : void MyFunc() {<여기에서 foo 클래스 정의>} 그러면 MyFunc 외부에서 'foo'를 참조 할 수 없습니다. 당신은 그것을 어떻게 든 보내야 만합니다. (물론 이미 알고 있습니다.) 나는 상속을 사용하는 것이 정당한 해결책이라고 생각한다. 그래서 투표 할 필요가 없다. "현재 범위에서 정의되지 않음"은 "현재 범위에서 액세스 할 수 없습니다"로 바꿔 쓸 수 있습니다.이 경우 MyFunc (또는 main) 내에서 값으로 boost :: function 상속을받는 다른 방법으로. – Asaf

+0

충분히 공정하게; 나는 말씨가 충분히 조심스럽지 않았다. 제 요점은 C++은 진정한 런타임 바인딩을 지원하지 않는다는 것입니다. 그 결과로 완전히 알려지지 않은 것을 호출 할 수 없다는 것입니다. 펑터에 관해서는 어떤 마법도 없습니다. foo는 main() 외부에서 완전히 알 수 없습니다. 상속 이건 뭐든간에 모든 솔루션은 foo (공용 실행 가능 인터페이스)의 본질을 main() 외부에서 액세스 할 수 있어야하며 컴파일 할 때해야합니다. COM은 아마도 가장 정교한 예일 것입니다. – Conal

1

함수 로컬 클래스를 템플릿 인수로 사용할 수 없다면 그 함수의 의미가됩니다. 이것은 C++ 0x에서만 지원됩니다.

1

로컬 클래스의 정적 함수 주소를 사용할 수 있습니다. 그러나 operator()는 비 정적 멤버 함수 여야하므로 이름을 부여해야합니다.

#include <iostream> 

template <class T> 
void bar(T f) 
{ 
    f(); 
} 

int main() 
{ 
    class foo { 
     public: 
     static void do_it() { 
      std::cout << "Hello" << std::endl; 
     } 
    }; 
    bar(&foo::do_it); 
    return 0; 
}