如何定义带有默认参数的std :: function变量? [英] How should I define a std::function variable with default arguments?
问题描述
要使用默认参数将std :: function变量设置为lambda函数,我可以使用 auto
,如下所示:
To set a std::function variable to a lambda function with default argument I can use auto
as in:
auto foo = [](int x = 10){cout << x << endl;};
foo();
这将打印10。
但是我希望foo变量驻留在结构中。在结构中,我不能使用 auto
。
But I want the foo variable to reside in a struct. In a struct I cannot use auto
.
struct Bar
{
auto foo = [](int x = 10}(cout << x << endl}; //error: non-static data member declared ‘auto’
};
Bar bar;
bar.foo();
替换 auto
具有std :: function
Replacing auto
with std::function
struct Bar
{
std::function<void(int x = 10)> foo = [](int x = 10}(cout << x << endl}; //error: default arguments are only permitted for function parameters
};
Bar bar;
bar.foo();
或
struct Bar
{
std::function<void(int)> foo = [](int x = 10}(cout << x << endl};
};
Bar bar;
bar.foo(); //error: no match for call to ‘(std::function<void(int)>) ()’
没有结构,将 auto
替换为std :: function:
Without the struct and replacing auto
for std::function:
std::function<void(int x)> foo = [](int x = 10){cout << x << endl;};
foo(); //error: no match for call to ‘(std::function<void(int)>) ()’
那么我应该如何声明foo?
So how should I declare foo?
推荐答案
std :: function中的签名
是基于您计划调用它的方式,而不是基于您构造/分配它的方式。由于要用两种不同的方式调用它,因此需要将其存储到不同的 std :: function
对象中,例如:
The signature in std::function
is based on how you plan to call it and not on how you construct/assign it. Since you want to call it two different ways, you'll need to store to different std::function
objects, as in:
struct Call
{
template<typename F>
explicit Call(F f) : zero_(f), one_(std::move(f)) {}
void operator()() { zero_(); }
void operator()(int i) { one_(i); }
std::function<void()> zero_;
std::function<void(int)> one_;
};
或者,您也可以自己进行类型擦除( std :: function
在后台进行操作)只存储一次lambda,例如:
Alternatively, you can do the type erasure yourself (what std::function
does behind the scenes) to only store the lambda once, as in:
class TECall
{
struct Concept
{
Concept() = default;
Concept(Concept const&) = default;
virtual ~Concept() = default;
virtual Concept* clone() const = 0;
virtual void operator()() = 0;
virtual void operator()(int) = 0;
};
template<typename T>
struct Model final : Concept
{
explicit Model(T t) : data(std::move(t)) {}
Model* clone() const override { return new Model(*this); }
void operator()() override { data(); }
void operator()(int i) override { data(i); }
T data;
};
std::unique_ptr<Concept> object;
public:
template<typename F>
TECall(F f) : object(new Model<F>(std::move(f))) {}
TECall(TECall const& that) : object(that.object ? that.object->clone() : nullptr) {}
TECall(TECall&& that) = default;
TECall& operator=(TECall that) { object = std::move(that.object); return *this; }
void operator()() { (*object)(); }
void operator()(int i) { (*object)(i); }
};
这篇关于如何定义带有默认参数的std :: function变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!