2017-02-28 16 views
8

Tôi chỉ vấp vào một vấn đề nhỏ mà làm phiền tôi trong khi đối phó với các mẫu. Dưới đây là một ví dụ:con trỏ chức năng templated như tham số mẫu

template<class _returnType, _returnType (*_function)()> 
_returnType aliasGetter() { return _function(); } 
int getCoolNumber() { return 42; } 
int main() 
{ 
    std::cout << aliasGetter<int, &getCoolNumber>(); //42 
} 

mã này làm việc (http://cpp.sh/ nếu bạn muốn thử nó), tuy nhiên kể từ khi tôi đưa ra một con trỏ hàm như mẫu thông số tôi không cần _returnType, nó phải có trong chữ ký chức năng, vấn đề là, cho dù tôi có cố gắng thế nào đi nữa, tôi không thể tìm ra cách để loại bỏ tham số mẫu bổ sung này.

Làm cách nào để tạo aliasGetter chỉ lấy một tham số mẫu (một con trỏ đến trình thu thập bí danh)? Nếu điều đó là không thể, tại sao không?

+0

Điều gì về việc sử dụng thông số mẫu đơn lẻ và dựa vào Khấu trừ đối số mẫu? – WhiZTiM

+1

@WhiZTiM Điều đó sẽ yêu cầu chuyển con trỏ hàm tới cuộc gọi lúc chạy. –

+0

Bạn cần nó bởi vì tham số mẫu thứ hai của bạn phụ thuộc vào nó. Bạn có thể xây dựng một cái gì đó với https://functionalcpp.wordpress.com/2013/08/05/function-traits/ nhưng tôi nghi ngờ rằng bạn sẽ lưu một tham số mẫu. – knivil

Trả lời

14

Trong C++ 17, nó sẽ trở thành có thể, nhờ template auto:

template <auto F> std::invoke_result_t<F> aliasGetter() { return F(); } 

Trước khi C++ 17, đó là không thể. Bạn cần chỉ định loại tham số mẫu không phải kiểu - không có cách nào xung quanh. Bạn không thể tạo một nhà máy cho điều này vì bạn không thể chuyển một con trỏ hàm thông qua một mẫu hàm và kết thúc nó như một đối số mẫu không kiểu.


Cách giải quyết ngắn nhất trong C++ 14 là, tiếng thở dài, sử dụng một macro:

template <class T, T F> std::result_of_t<T()> aliasGetter() { return F(); } 
#define TEMP_ALIAS(x) decltype(x), x 

std::cout << aliasGetter<TEMP_ALIAS(&getCoolNumber)>(); 

mà được bạn loại con trỏ chức năng của bạn mà không cần phải tự gõ nó hai lần.

+1

Tôi biết có thể với C + 17 nhờ cú pháp mới mà bạn mô tả, tuy nhiên, tôi nghĩ rằng có thể, nó có thể được thực hiện mà không có ma thuật lừa này (đó là lý do tại sao tôi gắn thẻ C++ 14). Nó vẫn là một câu trả lời tốt và rõ ràng mặc dù – Nyashes

+0

'std :: result_of' là [deprecated] (http://en.cppreference.com/w/cpp/types/result_of) trên C++ 17, sử dụng' std :: invoke_result 'thay vào đó. –

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