我需要提取函式物件引數的型別。
Lambda 被翻譯成帶有operator(). std::function也有operator()。
因此,我可以通過這種方式獲取指向operator()傳遞給另一個函式的指標:
template <typename F, typename T, typename R, typename ... Args>
void helper(F&, R (T::*)(Args...) const)
{
// do something with Args types
}
template <typename F>
void bar(F f)
{
helper(f, &F::operator());
}
void freefunc(int) {}
void foo()
{
// lambda: ok
bar([](int){});
// std::function: ok
const std::function<void(double)> f = [](double){};
bar(f);
// std::bind: does not compile
auto g = std::bind(freefunc, std::placeholders::_1);
bar(g);
}
std::bind也應該用 來創建一個物件operator()。但是,我的代碼不適用于std::bind(),我不明白為什么。
gcc 產生此錯誤:
In instantiation of 'void bar(F) [with F = std::_Bind<void (*(std::_Placeholder<1>))(int)>]':
<source>:58:8: required from here
<source>:47:11: error: no matching function for call to 'helper(std::_Bind<void (*(std::_Placeholder<1>))(int)>&, <unresolved overloaded function type>)'
47 | helper(f, &F::operator());
| ~~~~~~^~~~~~~~~~~~~~~~~~~
<source>:39:6: note: candidate: 'template<class F, class T, class R, class ... Args> void helper(F&, R (T::*)(Args ...) const)'
39 | void helper(F&, R (T::*)(Args...) const)
| ^~~~~~
<source>:39:6: note: template argument deduction/substitution failed:
<source>:47:11: note: couldn't deduce template parameter 'T'
47 | helper(f, &F::operator());
| ~~~~~~^~~~~~~~~~~~~~~~~~~
ASM generation compiler returned: 1
<source>: In instantiation of 'void bar(F) [with F = std::_Bind<void (*(std::_Placeholder<1>))(int)>]':
<source>:58:8: required from here
<source>:47:11: error: no matching function for call to 'helper(std::_Bind<void (*(std::_Placeholder<1>))(int)>&, <unresolved overloaded function type>)'
47 | helper(f, &F::operator());
| ~~~~~~^~~~~~~~~~~~~~~~~~~
<source>:39:6: note: candidate: 'template<class F, class T, class R, class ... Args> void helper(F&, R (T::*)(Args ...) const)'
39 | void helper(F&, R (T::*)(Args...) const)
| ^~~~~~
<source>:39:6: note: template argument deduction/substitution failed:
<source>:47:11: note: couldn't deduce template parameter 'T'
47 | helper(f, &F::operator());
做同樣事情的正確方法是什么std::bind?
uj5u.com熱心網友回復:
不幸的是,您想要做的事情是不可能的,因為std::bind標準的回傳型別過于松散。
std::function::operator()由標準明確定義,因此您可以將其與 匹配R (T::*)(Args... ),請參閱[func.wrap.func.general],- 對于 lambda 函式,從[expr.prim.lambda.closure#3]中并不清楚,但我會說它應該可以作業,
- 對于
std::bind,規范[func.bind.bind#4]更廣泛,因為它只說您可以呼叫g(u1, u2, …, uM)whereg的回傳值 fromstd::bind,因此不能保證std::bindeven 的回傳型別具有operator()成員函式。
這里實際的實作問題,gcc、clang和msvc都是一樣的,就是operator()回傳值的member-function其實是一個template,所以不能&F::operator()直接使用——不能取一個templated(member-)的地址功能。
uj5u.com熱心網友回復:
簡而言之 - 你不能這樣做,std::bind或者至少不能保證。盡管結果std::bind類似于閉包,但它是完全不同的。考慮一下如果以下類的某些事情是由于以下原因會發生什么std::bind:
class bind_result {
template<class T, class U>
U operator()(const T&);
private:
// implementation details
};
事實上,你的函式g不適用于這樣的類,因為它operator()是一個模板。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/415742.html
標籤:
