2015-11-15 20 views
7

Tôi muốn có hàm BindFirst liên kết đối số đầu tiên của hàm mà không cần phải biết rõ/trạng thái của hàm bằng cách sử dụng std :: placeholders. Tôi muốn mã khách hàng trông giống như vậy.ràng buộc đối số đầu tiên của hàm mà không biết tính chất của nó

#include <functional> 
#include <iostream> 

void print2(int a, int b) 
{ 
    std::cout << a << std::endl; 
    std::cout << b << std::endl; 
} 

void print3(int a, int b, int c) 
{ 
    std::cout << a << std::endl; 
    std::cout << b << std::endl; 
    std::cout << c << std::endl; 
} 

int main() 
{ 
    auto f = BindFirst(print2, 1); // std::bind(print2, 1, std::placeholders::_1); 
    auto g = BindFirst(print3, 1); // std::bind(print3, 1, std::placeholders::_1, std::placeholders::_2); 
    f(2); 
    g(2,3); 
} 

Bất kỳ ý tưởng nào có thể triển khai BindFirst?

Trả lời

8

Trong C++ 11:

#include <type_traits> 
#include <utility> 

template <typename F, typename T> 
struct binder 
{ 
    F f; T t; 
    template <typename... Args> 
    auto operator()(Args&&... args) const 
     -> decltype(f(t, std::forward<Args>(args)...)) 
    { 
     return f(t, std::forward<Args>(args)...); 
    } 
}; 

template <typename F, typename T> 
binder<typename std::decay<F>::type 
    , typename std::decay<T>::type> BindFirst(F&& f, T&& t) 
{ 
    return { std::forward<F>(f), std::forward<T>(t) }; 
} 

DEMO 1

Trong C++ 14:

#include <utility> 

template <typename F, typename T> 
auto BindFirst(F&& f, T&& t) 
{ 
    return [f = std::forward<F>(f), t = std::forward<T>(t)] 
      (auto&&... args) 
      { return f(t, std::forward<decltype(args)>(args)...); }; 
} 

DEMO 2

+0

tôi có thể biết tại sao 'std :: decay' là đã sử dụng? – billz

+0

@billz Bởi vì ở đây chúng tôi muốn lưu trữ các bản sao (có thể di chuyển được xây dựng) của các đối số được truyền cho 'BindFirst'. Bạn chắc chắn không muốn để lưu trữ tài liệu tham khảo, không phải của họ constness/volatileness là quan tâm của bạn ở đây. Nói, với 'T && = int &&' bạn muốn lưu trữ 'int' –

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