Alasannya adalah bahwa lambdas adalah objek fungsi sehingga meneruskannya ke templat fungsi akan instantiate fungsi baru khusus untuk objek itu. Dengan demikian kompiler dapat secara sepele menyejajarkan panggilan lambda.
Untuk fungsi, di sisi lain, peringatan lama berlaku: penunjuk fungsi dilewatkan ke templat fungsi, dan kompiler secara tradisional memiliki banyak masalah dalam mengurutkan panggilan melalui pointer fungsi. Mereka dapat secara teoritis inline, tetapi hanya jika fungsi sekitarnya inline juga.
Sebagai contoh, pertimbangkan templat fungsi berikut:
template <typename Iter, typename F>
void map(Iter begin, Iter end, F f) {
for (; begin != end; ++begin)
*begin = f(*begin);
}
Menyebutnya dengan lambda seperti ini:
int a[] = { 1, 2, 3, 4 };
map(begin(a), end(a), [](int n) { return n * 2; });
Hasil dalam Instansiasi ini (dibuat oleh kompiler):
template <>
void map<int*, _some_lambda_type>(int* begin, int* end, _some_lambda_type f) {
for (; begin != end; ++begin)
*begin = f.operator()(*begin);
}
... kompiler tahu _some_lambda_type::operator ()
dan bisa sebaris panggilan ke itu sepele. (Dan memohon fungsi map
dengan setiap lambda lain akan membuat Instansiasi baru map
karena masing-masing lambda memiliki tipe yang berbeda.)
Tetapi ketika dipanggil dengan function pointer, instantiation terlihat sebagai berikut:
template <>
void map<int*, int (*)(int)>(int* begin, int* end, int (*f)(int)) {
for (; begin != end; ++begin)
*begin = f(*begin);
}
... dan di sini f
menunjuk ke alamat berbeda untuk setiap panggilan map
dan dengan demikian kompiler tidak dapat inline panggilan ke f
kecuali panggilan sekitarnya map
juga telah diuraikan sehingga kompiler dapat menyelesaikan f
ke satu fungsi tertentu.