2017-02-13 35 views
6

Với mẫu variadic sau:Template khấu trừ cho các đối số lambda mẫu variadic

template<typename... Params> 
void fun(void(*f)(Params...), Params... params) { 
    f(params...); 
} 

int main() { 
    fun(+[](int a, int b) {}, 2, 3); 
} 

Đối với bây giờ khi gọi fun với một lambda tôi cần phải xác định loại của tất cả các đối số lambda một cách rõ ràng. Có vẻ như dư thừa kể từ khi int, int có thể được suy ra từ 2, 3. Có cách nào để làm cho nó ngắn gọn hơn và tự động hơn không?

Tôi muốn sau đây để làm việc, nhưng nó không:

template<typename... Params> 
void fun(void(*f)(Params...), Params... params) { 
    f(params...); 
} 

int main() { 
    fun(+[](auto a, auto b) {}, 2, 3); 
} 

Tôi đang biên soạn với g++ 5.4.0-std=c++14.

+1

Bạn gặp sự cố khi nhập 'int' thay vì' tự động'? – Brian

+0

@Brian Có, vì nó yêu cầu tôi suy luận rằng đó là 'int'. Nó có thể là bất cứ điều gì dài hơn để làm cho nó ấn tượng hơn. –

Trả lời

3

Đi chức năng bởi T thay vì bằng con trỏ:

template<typename T, typename... Params> 
void fun(T f, Params... params) { 
    f(params...); 
} 

int main() { 
    fun([](auto a, auto b) {}, 2, 3); 
} 

Bằng cách đó, trình biên dịch có thể chọn quá tải là quyền để gọi tại địa điểm cuộc gọi thay vì nếu bên các nhà điều hành +. Như đã nói trong bình luận, không có toán tử + được định nghĩa cho lambdas chung.


Ngoài ra, bạn có thể vô hiệu hóa các trình biên dịch từ cố gắng để suy Params từ con trỏ chức năng bằng cách sử dụng một bí danh sắc, nhưng tôi thực sự không khuyên bạn nên nó. Dù sao, ở đây bạn đi:

template<typename T> 
struct identity { using type = T; }; 

template<typename T> 
using identity_t = typename identity<T>::type; 

template<typename... Params> 
void fun(void(*f)(identity_t<Params>...), Params... params) { 
    f(params...); 
} 

int main() { 
    // v----- no unary +. That operator is not defined for generic lambdas. 
    fun([](auto a, auto b) {}, 2, 3); 
} 
+0

Lưu ý rằng không có toán tử '+' cho lambdas không chung chung. Toán tử '+' dựng sẵn được sử dụng, nhưng lambda do đó bị ép buộc tới một con trỏ sử dụng toán tử chuyển đổi của nó cho con trỏ hàm. – Brian

Các vấn đề liên quan