Neden çalışmıyor
Derleyicinin f()yineleyici türüne göre çözümlenmesini beklerdim . Görünüşe göre, (gcc 4.1.2) bunu yapmaz.
Durum böyle olsaydı harika olurdu! Ancak, for_eachaşağıdaki gibi bildirilen bir işlev şablonudur:
template <class InputIterator, class UnaryFunction>
UnaryFunction for_each(InputIterator, InputIterator, UnaryFunction );
Şablon çıkarımının UnaryFunction, çağrı noktasında bir tür seçmesi gerekir . Ancak fbelirli bir türü yoktur - aşırı yüklenmiş bir işlevdir, fher biri farklı türlerde birçok s vardır. İstediğini for_eachbelirterek şablon kesinti sürecine yardımcı olmanın güncel bir yolu yoktur f, dolayısıyla şablon kesinti başarısız olur. Şablon çıkarımının başarılı olması için çağrı sitesinde daha fazla iş yapmanız gerekir.
Düzeltmek için genel çözüm
Birkaç yıl ve C ++ 14 daha sonra burada umut. Aksine kullanım daha static_cast(şablon kesinti hangi "tespit" tarafından başarılı olmak için izin verecek olan fbiz kullanıma istiyoruz ama elle "düzeltme" Doğru birine aşırı yük çözünürlüğü yapmanızı gerektirir), bizim için derleyici çalışması yapmak istiyorum. fBazı argümanları çağırmak istiyoruz . Mümkün olan en genel şekilde, bu:
[&](auto&&... args) -> decltype(auto) { return f(std::forward<decltype(args)>(args)...); }
Yazması gereken çok şey var, ancak bu tür bir sorun sık sık rahatsız edici bir şekilde ortaya çıkıyor, bu yüzden bunu bir makroya (iç çekerek) sarabiliriz:
#define AS_LAMBDA(func) [&](auto&&... args) -> decltype(func(std::forward<decltype(args)>(args)...)) { return func(std::forward<decltype(args)>(args)...); }
ve sonra sadece kullanın:
void scan(const std::string& s) {
std::for_each(s.begin(), s.end(), AS_LAMBDA(f));
}
Bu, derleyicinin yapmasını istediğiniz şeyi tam olarak yapar - adın fkendisinde aşırı yük çözünürlüğü gerçekleştirir ve sadece doğru olanı yapar. Bu, fserbest bir işlev veya üye bir işlev olup olmadığına bakılmaksızın çalışır.