누구나 펑터를 도와 줄 수 있는지 궁금합니다. 나는 정말로 펑터가 무엇인지를 이해하지 못한다. 어떻게 작동하는지 나는 인터넷 검색을 시도했다. 그러나 나는 아직도 그것을 얻지 않는다. 펑터는 어떻게 작동하며 템플릿을 사용하는 방법은 무엇입니까?C++ 템플릿이있는 펑터
답변
Functor는 기본적으로 "함수 객체"입니다. 클래스 또는 구조체에 래핑 된 단일 함수이고 다른 함수에 전달할 수있는 함수입니다.
함수 호출 연산자 (operator())를 오버로드하는 고유 한 클래스 또는 구조체를 작성하여 작동합니다. 일반적으로 함수의 인수로 함수를 생성하는 functor가있는 곳에서 구현하면됩니다.
std::vector<int> counts;
지금, 당신은 그 벡터에 포함 된 모든 수를 증가 할 :
는 다음과 같은 있다고 가정합시다. 수동으로 루프를 반복하여 증가 시키거나 펑터를 사용할 수 있습니다. 적절한 펑은,이 경우에는 다음과 같이 보일 것이다 :struct IncrementFunctor
{
int operator() (int i)
{
return i + 1;
}
}
IncrementFunctor 지금의 정수를 받아 그것을 증가 펑터이다. 카운트에 적용하려면 함수로 인수를 취하는 std :: transform 함수를 사용할 수 있습니다.
std::transform(
counts.begin(), // the start of the input range
counts.end(), // the end of the input range
counts.begin(), // the place where transform should place new values.
// in this case, we put it right back into the original list.
IncrementFunctor()); // an instance of your functor
구문 IncrementFunctor()는 해당 펑터의 인스턴스를 생성 한 다음 std :: transform으로 직접 전달됩니다. 물론 인스턴스를 로컬 변수로 생성하여 전달할 수는 있지만 훨씬 편리합니다.
이제 템플릿을 참조하십시오. std :: transform에있는 functor의 형식은 템플릿 인수입니다. 이것은 std :: transform이 functor가 어떤 타입인지 알지 못하기 때문입니다. 이에 대한 관심 모두는 그것이
newValue = functor(oldValue);
컴파일러처럼 뭔가를 할 수있는 정의 피팅 연산자를(),이 템플릿에 대한 꽤 똑똑하고, 종종 템플릿 인자가 무엇인지 스스로 알아낼 수 있다는 것입니다 . 이 경우 컴파일러는 std :: transform에 템플릿 유형으로 정의 된 IncrementFunctor 유형의 매개 변수를 전달한다는 것을 자동으로 인식합니다. 그것은 당신에게 입력 꽤 저장
std::transform<std::vector<int>::iterator, // type of the input iterator
std::vector<int>::iterator, // type of the output iterator
IncrementFunctor>( // type of your functor
counts.begin(), // the start of the input range
counts.end(), // the end of the input range
counts.begin(), // the place where transform should place new values.
// in this case, we put it right back into the original list.
IncrementFunctor()); // an instance of your functor
: 컴파일러가 자동으로 실제 호출은 다음과 같이 것이라는 점을 인식하고, 그래서 그것은 역시 목록에 대해 동일한 작업을 수행합니다.)
펑터 구문이 괄호 안에 선택적 인수리스트와 ()
를 추가함으로써, 함수 호출 연산자 불려 호출 할 수있는 것을 /이다.
모든 템플릿이 필요합니다. 템플리트와 관련하여 이것이 호출되는 것은이 구문을 허용하는 것입니다. 즉, 자유 함수 또는 operator()()
을 대체하는 클래스의 인스턴스를 허용합니다. ("free"함수는 멤버가 아닌 것입니다. 즉 전역 범위의 함수이거나 이전에 포함 된 네임 스페이스의 범위에있는 함수입니다.) 템플릿 메타 프로그래밍의
외부, 우리는 일반적으로 무료 기능이 AA 펑터라고 말할 및 operator()()
을 재정의하는 클래스의 인스턴스에 대한 그 이름을 예약하지 않습니다
struct Foo {
public:
void operator()(int i) { // do something }
void operator()(int i, char x) { // do something else }
}
컴파일 당신이 실제로 _templated_ 펑터의 예를 보여 있기 때문에
template<typename T> class Bar {
private int j ;
public:
Bar(int i) : j(i) {}
void doIt(T t) {
t(j) ;
}
}
Foo f;
extern void resize(int i) ; // in some header
Bar<Foo> bf(5) ;
// a Bar that is templated on Foo
Bar< void (&)(int) > br(5) ;
// a Bar that is templated on a function taking int and returning void
br.doit(&resize) ; // call resize with br.j
bf.doit(f) ; // call Foo::operator()(int) on Foo f with bf.j
+1, 더 나은 답 : 그래서만큼 구문 이해을 만들면서, 컴파일러는 행복하게 함수 나 펑터를 사용합니다. –
그래도이'void (& (int))'구문은 무엇입니까? 그 사용법은 최소한 C++가 아닙니다. C++/CLI입니까? –
"이 void (& (int)) 구문은 어떻게 되나요?" 예, "int를 가져오고 void를 반환하는 함수의 주소"는 실수입니다. – tpdi