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_each
aş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 f
belirli bir türü yoktur - aşırı yüklenmiş bir işlevdir, f
her biri farklı türlerde birçok s vardır. İstediğini for_each
belirterek ş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 f
biz 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. f
Bazı 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 f
kendisinde aşırı yük çözünürlüğü gerçekleştirir ve sadece doğru olanı yapar. Bu, f
serbest bir işlev veya üye bir işlev olup olmadığına bakılmaksızın çalışır.