问题描述
我在move和lvalue语义上还很新。我有一种错的印象。在这里
一旦实现 FunctContainer
我想要编写的代码:
I'm pretty new in move and lvalue semantics. And I have the impression I'm doing it wrong. Herethe code I want to be able to write once FunctContainer
is implemented:
std::function<double(double)> f = [](double x){return (x * x - 1); };
FunctContainer fc1 = FunctContainer(f);
FunctContainer fc2 = FunctContainer([](double x){return (x * x - 1); });
我想写 FunctContainer
的代码因此,存储在 fc1
中的函数的生存期是 f
之一,而生存期在 fc2 包含的功能是 fc2
本身的生存期。
I want to write FunctContainer
's ctors so that the lifetime of the function stored in fc1
is the one of f
and the lifetime in fc2
of the contained function is the lifetime of fc2
itself.
我写了一些东西(见下文),但我不太满意(我弄错了)。
I have written something (see below) but I'm not really satisfied (I got it wrong).
这是正确的c ++,但行为错误:当 f _
是一个右值时, f _
在调用构造函数后到期。
This is correct c++ but wrong behavior: f_
expires after the call to the constructor when f_
is an rvalue.
class FunctContainerWRONG{
public:
IntegrandNotProjecting(const std::function<double(double)>& function)
: f_(function){}
IntegrandNotProjecting(const std::function<double(double)>&& function)
: f_(std::move(function)){}
const std::function<double(double)>& f_;
private:
};
这对我来说似乎很糟糕,可能不是正确的c ++,但旨在用伪代码解释所需的内容行为看起来像。如果可能,我想避免构造一个全新的对象,而只想让我的对象持久:
This looks awful at me and probably is not correct c++ but is intended to explain in pseudocode what the desired behavior looks like. If possible I want to avoid to constuct a brand new object and I just want to let my object "persist":
class FunctContainer{
public:
FunctContainer(const std::function<double(double)>& function)
: f_p(nullptr),
f_(function){}
FunctContainer(const std::function<double(double)>&& function)
: f_p()std::make_shared<std::function<double(double)>>(function)),
f_(*f_p){}
private:
std::shared_ptr<std::function<double(double)>> f_p;
const std::function<double(double)>& f_;
};
推荐答案
转发参考和引用折叠规则可以帮助您轻松实现这一目标。
Forwarding references and reference collapsing rules can help you achieve this easily.
template <typename T>
struct FunctContainer
{
T _f;
template <typename TFwd>
FunctContainer(TFwd&& f) : _f{std::forward<TFwd>(f)} { }
};
template <typename T>
auto makeFunctContainer(T&& f) -> FunctContainer<T>
{
return {std::forward<T>(f)};
}
-
调用<$ c带有左值,
T
的$ c> makeFunctContainer 将是左值引用。这意味着您将在FucntContainer
内存储左值引用。When you invoke
makeFunctContainer
with an lvalue,T
will be an lvalue reference. This means that you'll store an lvalue reference insideFucntContainer
.当您使用 rvalue 调用
makeFunctContainer
时,T
将是一个值。这意味着您将在FucntContainer
中存储一个 value 。When you invoke
makeFunctContainer
with an rvalue,T
will be a value. This means that you'll store a value insideFucntContainer
.示例用法:
auto fc0 = makeFunctContainer(std::move(f0)); // `fc0` owns `f0` auto fc1 = makeFunctContainer(f1); // `fc1` stores a reference to `f1`
这篇关于如果是左值,请参考;如果是右值,请进行复制,即使右值保持不变的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!