如果我有一個類需要以類方法作為引數呼叫父類方法,我可以使用std::function 來完成std::bind,如下所示:
class A {
void complexMethod(std::function<void()> variableMethod) {
// other stuff ...
variableMethod();
// some other stuff..
}
}
class B : public A {
void myWay() {
// this and that
}
void otherWay() {
// other and different
}
void doingSomething() {
// Preparing to do something complex.
complexMethod(std::bind(&B::myWay, this));
}
void doingAnotherThing() {
// Different preparation to do some other complex thing.
complexMethod(std::bind(&B::otherWay, this));
}
}
我需要如何更改上面的代碼以使用模板而不是std::function 來實作相同的東西std::bind?
那么 lambdas 而不是std::function std::bind呢?我仍然想打電話B:myWay()但B::otherWay()使用 lambdas。我不想B:myWay()用B::otherWay()lambdas 代替。
是否有任何實作技術(上述之一或其他)我能夠variableMethod明確回傳型別和引數?我該怎么做?假設簽名variableMethod是:
bool variableMethod(int a, double b);
推薦哪種技術?為什么(速度、靈活性、易用性……)?
uj5u.com熱心網友回復:
模板 lambda 解決方案:
struct A
{
template <typename F>
void runA(F func)
{
cout << 1 << endl;
func();
cout << 3 << endl;
}
};
struct B : A
{
int number = 2;
void runnable() { cout << number << endl; }
void runB()
{
cout << 0 << endl;
runA([this]() { runnable(); });
cout << 4 << endl;
}
};
int main()
{
B variable;
variable.runB();
}
為了將函式作為模板引數,只需像上面那樣接受該函式的模板型別。可以使用lambdasthis代替 bind 使事情變得更容易(傳遞給 lambda 捕獲串列)。
顯式宣告引數:
void run_func(std::function<bool(int, double)> func)
{
bool b = func(10, 10.01);
}
std::function 允許您像上面一樣定義您的爭論和回傳型別。
uj5u.com熱心網友回復:
我需要如何更改上面的代碼以使用模板而不是
std::function來實作相同的東西std::bind?那么 lambdas 而不是
std::functionstd::bind呢?我仍然想打電話B:myWay()但B::otherWay()使用 lambdas。我不想B:myWay()用B::otherWay()lambdas 代替。
您可以使用 lambda,是的。
像[this]() { return myWay(); }這樣的東西:
- 捕獲
this,并且 - 呼叫當前物件的方法。
[演示]
#include <iostream> // cout
class A {
protected:
template <typename F>
void complexMethod(F&& f) { f(); }
};
class B : public A {
void myWay() { std::cout << "myWay\n"; }
void otherWay() { std::cout << "otherWay\n"; }
public:
void doingSomething() {
complexMethod([this]() { return myWay(); });
}
void doingAnotherThing() {
complexMethod([this]() { return otherWay(); });
}
};
int main() {
B b{};
b.doingSomething();
b.doingAnotherThing();
}
// Outputs:
//
// myWay
// otherWay
是否有任何實作技術(上述之一或其他)我能夠
variableMethod明確回傳型別和引數?我該怎么做?
您可以將const std::function<bool(int,double)>& f其用作接收函式的引數complexMethod。并且仍然通過一個 lambda。請注意,盡管 lambdas 現在正在接收(int i, double d)(也可能是(auto i, auto d)這樣)。
[演示]
#include <functional> // function
#include <ios> // boolalpha
#include <iostream> // cout
class A {
protected:
bool complexMethod(const std::function<bool(int,double)>& f, int i, double d)
{ return f(i, d); }
};
class B : public A {
bool myWay(int a, double b) { return a < static_cast<int>(b); }
bool otherWay(int a, double b) { return a*a < static_cast<int>(b); }
public:
bool doingSomething(int a, double b) {
return complexMethod([this](int i, double d) {
return myWay(i, d); }, a, b);
}
bool doingAnotherThing(int a, double b) {
return complexMethod([this](auto i, auto d) {
return otherWay(i, d); }, a, b);
}
};
int main() {
B b{};
std::cout << std::boolalpha << b.doingSomething(3, 5.5) << "\n";
std::cout << std::boolalpha << b.doingAnotherThing(3, 5.5) << "\n";
}
// Outputs:
//
// true
// false
請注意,模板也可以實作相同的功能,盡管您不會明確簽名。
[演示]
#include <functional> // function
#include <ios> // boolalpha
#include <iostream> // cout
class A {
protected:
template <typename F, typename... Args>
auto complexMethod(F&& f, Args&&... args) -> decltype(f(args...))
{ return f(args...); }
};
class B : public A {
bool myWay(int a, double b) { return a < static_cast<int>(b); }
bool otherWay(int a, double b) { return a*a < static_cast<int>(b); }
public:
bool doingSomething(int a, double b) {
return complexMethod([this](auto i, auto d) {
return myWay(i, d); }, a, b);
}
bool doingAnotherThing(int a, double b) {
return complexMethod([this](auto i, auto d) {
return otherWay(i, d); }, a, b);
}
};
int main() {
B b{};
std::cout << std::boolalpha << b.doingSomething(3, 5.5) << "\n";
std::cout << std::boolalpha << b.doingAnotherThing(3, 5.5) << "\n";
}
// Outputs:
//
// true
// false
推薦哪種技術?為什么(速度、靈活性、易用性……)?
Scott Meyer 的 Effective Modern C 一書的第 34 項標題為Prefer lambdas to std::bind. 它以一句話結尾:Lambdas are more readable, more expressive, and may be more efficient than using std::bind. 但是,它還提到了一個std::bind可能對 lambda 有用的情況。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/412634.html
標籤:
上一篇:QML從QML或C 更新Gridview而不發出dataChanged
下一篇:使用模板化大整數的二進制除法
