왜 안돼?
컴파일러가 f()
반복자 유형 으로 해결 될 것으로 기대합니다 . 분명히 (gcc 4.1.2) 그렇게하지 않습니다.
그 경우라면 좋을 것입니다! 그러나 for_each
함수 템플릿은 다음과 같이 선언됩니다.
template <class InputIterator, class UnaryFunction>
UnaryFunction for_each(InputIterator, InputIterator, UnaryFunction );
템플릿 공제 UnaryFunction
는 통화 시점에 유형을 선택해야합니다 . 그러나 f
특정 유형이 없습니다-과부하 된 기능이므로 f
각각 다른 유형을 가진 많은 것이 있습니다. 현재 for_each
템플릿 공제 프로세스를 지원할 수있는 방법은 없습니다.f
원하는 것을 템플릿 공제가 단순히 실패합니다. 템플릿 공제에 성공하려면 콜 사이트에서 더 많은 작업을 수행해야합니다.
그것을 고치는 일반적인 해결책
몇 년 동안 여기에오고 나중에 C ++ 14. 오히려 사용을보다가 static_cast
(템플릿 공제하는 "고정"으로 성공할 수 있도록 것이다 f
우리가 사용하고자하지만, 수동으로 "수정"올바른 일에 오버로드 확인을 수행 할 필요), 우리는 우리를 위해 컴파일러 작품을 만들고 싶어. 우리는 f
일부 인수 를 요청하고 싶습니다 . 가능한 가장 일반적인 방법으로,
[&](auto&&... args) -> decltype(auto) { return f(std::forward<decltype(args)>(args)...); }
타이핑하기는 쉽지만 이런 종류의 문제는 성가신 일이 자주 발생하므로 매크로로 한 번 감싸는 것이 좋습니다.
#define AS_LAMBDA(func) [&](auto&&... args) -> decltype(func(std::forward<decltype(args)>(args)...)) { return func(std::forward<decltype(args)>(args)...); }
그런 다음 사용하십시오.
void scan(const std::string& s) {
std::for_each(s.begin(), s.end(), AS_LAMBDA(f));
}
이것은 컴파일러가 원하는 것을 정확하게 수행합니다-이름 f
자체 에 대한 과부하 해결을 수행하고 올바른 일을하십시오. 이것은 f
무료 기능인지 멤버 기능 인지에 관계없이 작동 합니다.