如果lvalue,请参考,如果rvalue进行复制,即使rvalue持久
Take a reference if lvalue and make a copy if rvalue i.e. make rvalue persistent
我在移动和LVALUE语义上很新。我的印象是我做错了。这里实现FunctContainer
后,我想编写的代码:
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
的ctors,以便在fc1
中存储的函数的寿命是f
之一,并且包含功能的fc2
中的寿命是fc2
本身的寿命。
我写了一些东西(见下文),但我不太满意(我错了)。
这是正确的C ,但错误的行为:f_
在f_
是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 ,但旨在在伪代码中解释所需的行为是什么样的。如果可能
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_;
};
转发参考和参考contapapsing 规则可以帮助您轻松实现此目标。
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)};
}
当您使用 lvalue 调用
makeFunctContainer
时,T
将是 lvalue参考。这意味着您将在FucntContainer
中存储 lvalue参考。当您使用 rvalue 调用
makeFunctContainer
时,T
将是 value 。这意味着您将在FucntContainer
中存储A value 。
示例用法:
auto fc0 = makeFunctContainer(std::move(f0)); // `fc0` owns `f0`
auto fc1 = makeFunctContainer(f1); // `fc1` stores a reference to `f1`
以来,由于C 17具有使用用户定义的扣除指南(类模板参数扣除)的类模板参数扣除。因此,您可以如下解决问题:
#include <utility>
#include <iostream>
template<typename FnT>
struct FunctContainer {
constexpr FunctContainer(FnT f) : f_ { std::forward<FnT>(f) } {}
FnT f_;
};
template<typename FnT>
FunctContainer(const FnT& f) -> FunctContainer<const FnT&>;
template<typename FnT>
FunctContainer(FnT&& f) -> FunctContainer<FnT>;
int
main(
) {
auto f { [] { std::cout << "Hello, world!" << std::endl; } };
FunctContainer f1 { f }; // stores reference to f in f1
FunctContainer f2 { [] { std::cout << "Hello, world!" << std::endl; } }; // moves f into f2
f1.f_();
f2.f_();
return 0;
}
相关文章:
- 如果没有malloc,链表实现将失败
- 对RValue对象调用的LValue ref限定成员函数
- 如果我只是不访问queue_front节点的子节点,而是将它们推到队列中呢?还是BFS吗
- std::map<struct,struct>::find 找不到匹配项,但是如果我循环通过 begin() 到 end(),我在那里看到匹配项
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 获取日期异步信号安全吗?如果在信号处理程序中使用,它会导致死锁吗
- 设计一个只能由特定类实例化的类(如果可能的话,通过make_unique)
- 线程,如果else语句,都是错误的上下文切换后,会发生什么
- 如果编译的源代码是特定于它编译的硬件的,我们如何分发它
- 如果我std::dynamic_pointer_cast并且底层dynamic_cast的结果为null,那么返回的sh
- C++擦除(如果存在)
- 如果"new int"返回"int*",那么为什么"new int[n]"不返回"int**"?
- 在'如果'陈述输出如何正确
- 如果用户输入无效,如何使用字符串变量-C++重复输入命令
- 如果有一个模板构造函数只有一个泛型参数,为什么我必须有一个复制构造函数
- 如果基类包含双指针成员,则派生类的构造函数
- 如果没有数学库,我如何在C++中创建复利公式
- 如果没有带有函数签名的 rvalue 参数,是否会执行 C++ 11 中的移动语义?
- 为什么函数调用是xvalue(如果返回类型为rvalue)
- 如果lvalue,请参考,如果rvalue进行复制,即使rvalue持久