2015-06-24 22 views
10

Bir yakalama lambda'sını şablon parametresi olarak şablonlu işlev işaretçisi işlevine geçiremediğimi fark ediyor. Yanlış şekilde mi yapıyorum yoksa imkansız mı? f2constexpr olmadığı içinİşlev olarak işaretleme işleviyle şablon lambda olarak şablon parametresinin geçirilmesi

#include <iostream> 

// Function templated by function pointer 
template< void(*F)(int) > 
void fun(int i) 
{ 
    F(i); 
} 

void f1(int i) 
{ 
    std::cout << i << std::endl; 
} 

int main() 
{ 
    void(*f2)(int) = [](int i) { std::cout << i << std::endl; }; 

    fun<f1>(42); // THIS WORKS 
    f2(42);  // THIS WORKS 
    fun<f2>(42); // THIS DOES NOT WORK (COMPILE-TIME ERROR) !!! 

    return 0; 
} 
+0

'std :: function' işlevini kullanın. – 101010

+1

f2, bir değişken çalışma zamanı parametresidir. Şablonlar, zaman parametreleri oluşturmayı gerektirir (sabitler ve tipler). Const eklemeyi deneyin, ancak muhtemelen işe yaramaz. – Hcorg

cevap

11

Çoğunlukla dilin tanımı bir sorun, şu olduğunu daha belirgin hale getirir:

using F2 = void(*)(int); 

// this works: 
constexpr F2 f2 = f1; 

// this does not: 
constexpr F2 f2 = [](int i) { std::cout << i << std::endl; }; 

Live example

Bu temel olarak, umudunuzun/beklentinizin oldukça makul olduğu anlamına gelir, ancak dil şu anda bu şekilde tanımlanmamıştır - bir lambda, constexpr olarak uygun bir işlev göstergesini vermez.

Bu sorunu düzeltmek için bir öneri var: N4487.

4

Bu açıdan uygun değildir (yani, bir çalışma zamanı değişkendir). Bu şekilde şablon parametresi olarak kullanılamaz. Eğer kodu değiştiremez ve aşağıdaki şekilde daha genel yapabiliriz:

#include <iostream> 

template<typename F, typename ...Args> 
void fun(F f, Args... args) { 
    f(args...); 
} 

void f1(int i) { 
    std::cout << i << std::endl; 
} 

int main() { 
    auto f2 = [](int i) { std::cout << i << std::endl; }; 
    fun(f1, 42); 
    f2(42); 
    fun(f2, 42); 
    return 0; 
} 
İlgili konular