2015-06-24 13 views
10

Wygląda na to, że nie mogę przekazać lambda bez przechwytywania jako parametru szablonu do funkcji szablonowej według funkcji-wskaźnika. Czy robię to w niewłaściwy sposób, czy jest to niemożliwe?Przekazanie lambda jako parametru szablonu do szablonu na podstawie funkcji wskaźnik-funkcja

#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

Użyj 'std :: function'. – 101010

+1

f2 jest zmienną - parametr wykonawczy. Szablony wymagają parametrów czasu kompilacji (stałych i typów). Spróbuj dodać const, ale prawdopodobnie nie będzie działać. – Hcorg

Odpowiedz

11

To głównie problem w definicji Językiem za dodaje czyni go bardziej oczywiste:

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

Zasadniczo oznacza to, że twoja nadzieja/oczekiwanie jest całkiem rozsądna, ale język nie jest obecnie zdefiniowany w ten sposób - lambda nie daje wskaźnika funkcji, który jest odpowiedni jako constexpr. Jest to jednak propozycja rozwiązania tego problemu: N4487.

4

nie jest opłacalne ponieważ f2constexpr nie (to znaczy jest to zmienna wykonania). Jako taki nie może być używany jako parametr szablonu. Można zmienić swój kod i uczynić go bardziej rodzajowe w następujący sposób:

#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; 
} 
Powiązane problemy