我想將 std::bind 與模板函式一起使用。有可能嗎?
PS 使用很重要std::bind
,因為我通過 lambdas 知道至少一種解決方案,并且想知道是否有 std::bind 解決方案。
#include <iostream>
#include <functional>
#include <memory>
using namespace std;
struct foo : std::enable_shared_from_this<foo>
{
void f()
{
// doesn't compile, error : no matching function for call to 'bind'
auto cb = std::bind(&foo::handle, shared_from_this(), placeholders::_1, placeholders::_2);
}
template <typename T, typename U>
void handle(T, U)
{
}
};
int main()
{
return 0;
}
uj5u.com熱心網友回復:
handle
不是模板函式。沒有“模板功能”。handle
是一個函式模板,即它是一個模板,它不是一個函式。您不能std::bind
使用模板。你只能std::bind
給一個callable。
訣竅是將模板的實體化和模板引數的推導推遲到實際呼叫函式時:
#include <iostream>
#include <functional>
#include <memory>
using namespace std;
struct foo {
struct handle_caller {
template <typename T,typename U>
void operator()(foo* f, T t,U u){
f->handle(t,u);
}
};
void f()
{
auto cb = std::bind(handle_caller{},this, placeholders::_1, placeholders::_2);
}
template <typename T, typename U>
void handle(T, U)
{
}
};
int main()
{
return 0;
}
傳遞給 bind 的可呼叫物件是一個具體型別的物件handle_caller
。它不是模板。只有當cb
被呼叫時,引數才會被轉發到handle_caller::operator()
可以推匯出模板引數的地方。
Lambda 可以開箱即用地做到這一點,因為帶有auto
引數的 lambda 是一個具體型別,并且只有它operator()
是一個模板:
#include <iostream>
#include <functional>
#include <memory>
using namespace std;
struct foo {
void f()
{
auto cb = std::bind([](auto f,auto t,auto u){ f->handle(t,u);},this, placeholders::_1, placeholders::_2);
}
template <typename T, typename U>
void handle(T, U)
{
}
};
int main()
{
return 0;
}
但是,一旦您使用 lambda,就不再需要std::bind
了,因為您可以通過 lambda 捕獲系結引數。std::bind
是系結引數的古老方式,它很復雜,語法也很笨拙。我讀過可以用 lambda 完成std::bind
但不能用 lambda 完成的案例,但我從未遇到過。
PS:請注意,我shared_from_this
從您的代碼中洗掉了這些東西,因為我知道它很容易被錯誤地使用,但我不確定如何正確使用它。由于cb
只是本地的,foo::f
因此無需擔心this
示例代碼中的生命周期。
uj5u.com熱心網友回復:
&foo::handle
不是有效的 C ,因為foo::handle
它不是函式。foo::handle<int, int>
是一個函式,并且foo::handle<double, std::string>
是一個不同的函式。
您必須將其包裝在某些東西中,因此您不妨使用 lambda。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/428009.html
上一篇:從用戶代碼中注入默認模板引數型別