我會解釋給我最大的能力。首先,_1
不過是一個全局變量。在這方面沒有什麼特別的,它也可以命名爲其他任何東西 - placeholder1
或SergeyA
。然而,像_1
名短,具有很好理解的含義,並與_
,從而降低它與程序中的其它全球衝突的名字可能性開始。
神奇的是在該變量的類型。它有一個特殊的類型,它反映在生成的bind*
對象中。之後,當調用operator()
時,該類型被認爲是從operator()
參數中獲取參數。
下面是一些說明C++ - 像僞代碼,這是不正確的,但說明:
template<class F, class... ARG>
struct bound {
bound(F f, ARGS&&... args) : bound_args(args...), functor(f) { }
std::tuple<ARG...> bound_args;
template<class... T>
void operator()(T&&... args);
F f;
};
template<class F, class... T>
auto bind(F f, T&& args) {
return bound<std::remove_reference_t<T>...>(f, args...);
}
現在,讓我們引入一個佔位符類型。
template<size_t N>
struct placeholder {
enum { position = N; };
template<class...T>
auto operator()(T&&... args) {
return std::get<position>(std::make_tuple(arg...));
}
};
placeholder<0> _1;
placeholder<1> _2;
到目前爲止這麼好。現在,讓我們看看運營商()的實際工作原理綁定的對象上:這裏
template<class... BOUND_ARGS>
template<class... CALL_ARGS>
void bound_object<BOUND_ARGS...>::operator() (CALL_ARGS&&... args) {
call_impl(args..., make_index_sequence<sizeof...(BOUND_ARGS)>{});
}
make_index_sequence是需要的元組值提取到函數的參數,所以不要太在意它。這裏是call_impl;
template<class... BOUND_ARGS>
template<class... CALL_ARGS, size_t... ix>
void bound_object<BOUND_ARGS...>::call_impl(CALL_ARGS&&... args, std::index_sequence<ix...>) {
f(to_arg().(std::get<ix>(bound_args), args...)...);
}
而且拼圖的最後一塊是to_arg
:
template<class B, class... ARGS>
auto to_arg(B&& b, ARGS... args) {
return b;
}
template<class... ARGS>
auto to_arg(placeholder<0> p, ARGS&&... args) {
return p(args);
}
template<class... ARGS>
auto to_arg(placeholder<1> p, ARGS&&... args) {
return p(args);
}
的to_arg
這裏全是給你要麼綁定參數或所提供的一個參數的基礎上,結合參數類型。在我上面的例子中,我使用了3個重載,因爲你可以部分地專門化一個函數,但是當然,把它放在一個類中並部分地專門化這個類會更有意義。
參見在其上的標準文檔http://en.cppreference.com/w/cpp/utility/functional/placeholders因爲它們加入C++ 11。基本上他們只是特定的類型和價值,「綁定」知道如何解釋。 – clcto
編譯器將'_1'解釋爲名稱,與解釋'x'相同。該名稱的實現位於boost庫中,該庫是開源的,因此您可以自行檢查它。 –
但你能解釋其中'_1'被映射到'A.G(2)傳遞的參數完整的機制;' – Rama