2012-06-16 45 views
6

xem xét:chuyên môn hóa từng phần của một mẫu

template <typename Function, typename ...Args> 
auto wrapper(Function&& f, Args&&... args) -> decltype(f(args...)) { 
//... 
} 

Có cách nào để phần chuyên các mẫu trên cho tất cả các trường hợp decltype(f(args...)) là một con trỏ?

EDIT:
Tôi nghĩ rằng nó có thể được thực hiện với một lớp helper mẫu mà mất decltype(f(args...)) như mẫu đối số, và chuyên lớp helper. Nếu bạn biết các giải pháp tốt hơn hãy cho tôi biết.

Trả lời

3

giải pháp Một SFINAE dựa trên:

#include <type_traits> 

template< 
    typename Functor 
    , typename... Args 
    , typename Result = decltype(std::declval<Functor&>()(std::declval<Args>()...)) 
    , typename std::enable_if< 
     std::is_pointer<Result>::value 
     , int 
    >::type = 0 
> 
Result wrapper(Functor&& functor, Args&&... args) 
{ /* ... */ } 

template< 
    typename Functor 
    , typename... Args 
    , typename Result = decltype(std::declval<Functor&>()(std::declval<Args>()...)) 
    , typename std::enable_if< 
     !std::is_pointer<Result>::value 
     , int 
    >::type = 0 
> 
Result wrapper(Functor&& functor, Args&&... args) 
{ /* ... */ } 

Bạn có thể thích nghi với các bài kiểm tra (ở đây, std::is_pointer<Result>) yêu cầu của bạn.

1

Khi bạn thấy loại trả về không phải là đối số mẫu hoặc một phần của đối số, do đó bạn không thể quá tải hoặc không chuyên môn. Công văn trên một người trợ giúp là lựa chọn tốt nhất của bạn.

#include <type_traits> 

template<typename Func, typename... Args> 
void func_impl(Func&& f, Args&&... args, std::true_type) 
-> decltype(func_impl(std::forward<Args>(args)...)) 
{ } 

template<typename Func, typename... Args> 
void func_impl(Func&& f, Args&&... args, std::false_type) 
-> decltype(func_impl(std::forward<Args>(args)...)) 
{ } 

template<typename Func, typename... Args> 
auto func(Func&& f, Args&&... args) 
    -> decltype(func_impl(std::forward<Func>(f), std::forward<Args>(args)...)) 
{ return func_impl(std::forward<Func>(f), std::forward<Args>(args)..., 
        std::is_pointer<decltype(f(std::forward<Args>(args)...))>::type); } 

Có vẻ hơi lạ khi tôi thực hiện chức năng này bằng tham chiếu rvalue và bạn cũng bỏ qua chuyển tiếp trong ví dụ ban đầu của mình.

Một giải pháp khác có thể là đối số mặc định mẫu và quá tải trên đó. Nhưng điều đó sẽ không hoạt động tốt với danh sách đối số.

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