for_each
템플릿의 마지막 매개 변수는 functor입니다. Functor은 ()
연산자 (가능한 경우 인수가 있음)를 사용하여 "호출 할 수있는"것입니다.
- 일반 비 멤버 함수 펑있다 : (고화질)으로 펑 두 가지 특색이있다.
- 과부하 된
()
연산자 (따라서 함수 개체)가있는 클래스 형식의 개체도 펑터입니다. 당신이 for_each
에 대한 펑로 일반적인 기능을 사용하기를 원한다면
지금, 그것은 for_each
템플릿 [추론] 인수 인스턴스화이 경우 다음
inline void do_something(int &i) { /* do something */ }
int main() {
int array[10];
std::for_each(array, array + 10, &do_something);
}
처럼 보일 것이다 <int *, void (*)(int &)>
. 이 경우 실제 펑터 값은 함수 포인터로 전달 된 함수 포인터 &do_something
입니다. for_each
의 관점에서 이것은 런타임 값입니다. 런타임 값이기 때문에 펑터에 대한 호출을 인라인 할 수 없습니다. (함수 포인터를 통해 만들어진 모든 호출을 인라인하는 것은 일반적으로 불가능합니다.
하지만 우리는 대신에 함수 객체를 사용하는 경우 for_each
템플릿 [추론] 인수 <int *, do_something>
인스턴스화되고이 경우
struct do_something {
void operator()(int &i) { /* do something */ }
};
int main() {
int array[10];
std::for_each(array, array + 10, do_something());
}
을 다음과 같이 코드를 볼 수 있습니다. 내부 for_each
에서 펑터에 대한 호출은 do_something::operator()
으로 연결됩니다. 호출 대상은 컴파일 타임에 알려지고 고정됩니다. 대상 함수는 컴파일 타임에 알려지기 때문에 호출을 쉽게 인라인 할 수 있습니다.
물론 후자의 경우에는 for_each
에 인수로 전달 된 런타임 값이 있습니다. for_each
에 전화 할 때 우리가 만드는 do_something
클래스의 [일시적] 임시 인스턴스 일 수 있습니다. 그러나이 런타임 값은 호출 대상에 영향을주지 않으므로 (operator()
이 가상 인 경우 제외) 인라인에 영향을 미치지 않습니다.
출처
2010-02-08 23:35:02
AnT
그러나':: std :: for_each'의 완전한 정의는 컴파일러에서 사용할 수 있습니다. 똑똑한 컴파일러에게는 인라인으로 선언 된 함수의 주소가되는 특정 인수로 호출되는 것을 볼 수 있습니다. 컴파일러는 클래스 메소드 인 것처럼 함수 호출을 인라인 할 수 있어야합니다. – Omnifarious
@Omnifarious : 내 예제에서 당신은'void (int &)'시그너쳐를 갖는 다른 함수로 for_each를 호출 할 수 있으며 컴파일러는 for_each와 동일한 하나의 인스턴스 생성만을 사용합니다 : for_each
AnT
예를 들어 (템플릿에 대해 잊어 버려), 내 프로그램에서'void foo (int)'함수를 가지고'foo (1);로 여러 번 호출하면; foo (2); '나는 컴파일러가'foo'에 대해 하나의 함수 본문을 생성하고 다른 인수로 동일한 본문을 실행하도록 기대합니다 : 1, 2, 3. 대신에 컴파일러가'foo '각각 "inlined"상수 1, 2, 3을 사용하면 나는 놀랄 것입니다. 작은'foo'에 대해서는 (그 후 인라인된다면) 괜찮을 것이지만, 더 큰'foo'에 대해서는 바람직하지 않습니다. 당신이 묘사하는 것은 본질적으로 같은 것입니다. – AnT