2015-06-24 16 views
10

Có vẻ như tôi không thể truyền một lambda không bắt giữ làm tham số mẫu cho một templated bởi hàm con trỏ hàm. Tôi đang làm điều đó một cách sai lầm, hay là không thể?Truyền lambda làm tham số mẫu để templated bởi hàm con trỏ hàm

#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

Sử dụng 'std :: function'. – 101010

+1

f2 là tham số biến thời gian chạy. Mẫu yêu cầu thông số thời gian xây dựng (hằng số và loại). Hãy thử thêm const, nhưng nó có thể sẽ không hoạt động. – Hcorg

Trả lời

11

Đó chủ yếu là một vấn đề trong định nghĩa của ngôn ngữ, sau đây làm cho nó rõ ràng hơn:

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

Điều này về cơ bản có nghĩa là hy vọng/kỳ vọng của bạn là khá hợp lý, nhưng ngôn ngữ hiện không được định nghĩa theo cách đó - một lambda không mang lại một con trỏ hàm thích hợp như là constexpr.

Tuy nhiên, đề xuất khắc phục vấn đề này: N4487.

4

Đây không phải là khả thi vì f2 không phải là constexpr (ví dụ, là một biến runtime). Vì vậy, nó không thể được sử dụng như một tham số mẫu. Bạn có thể thay đổi mã của bạn và làm cho nó chung chung hơn theo cách thức sau đây:

#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; 
} 
Các vấn đề liên quan